001/*
002 * Copyright (c) 2026, Oracle and/or its affiliates.
003 *
004 * Licensed under the Universal Permissive License Version 1.0 as shown at
005 * https://oss.oracle.com/licenses/upl/
006 */
007package com.oracle.database.selectai.model;
008
009import com.fasterxml.jackson.annotation.JsonInclude;
010import com.fasterxml.jackson.annotation.JsonIgnore;
011import com.fasterxml.jackson.databind.ObjectMapper;
012import com.fasterxml.jackson.databind.PropertyNamingStrategies;
013
014/**
015 * Typed parameters payload for {@code DBMS_CLOUD_AI.SUMMARIZE}.
016 * <p>
017 * This model lets Java callers configure summarization without manually
018 * constructing JSON. It serializes to the snake_case names expected by
019 * {@code DBMS_CLOUD_AI.SUMMARIZE}.
020 * <p>
021 * This model represents the JSON payload supplied to the {@code params}
022 * argument of {@code DBMS_CLOUD_AI.SUMMARIZE}. It serializes Java fields to
023 * the snake_case names expected by the database, such as {@code min_words},
024 * {@code max_words}, {@code summary_style},
025 * {@code chunk_processing_method}, and {@code extractiveness_level}.
026 *
027 * @see <a href="https://docs.oracle.com/en/cloud/paas/autonomous-database/serverless/adbsb/dbms-cloud-ai-package.html#GUID-90D2E0E6-1EF1-4275-9927-8E0613FD305D">
028 *      DBMS_CLOUD_AI summarize parameters</a>
029 */
030public final class SummaryParams {
031
032    /** Approximate minimum summary word count. */
033    private final Integer minWords;
034    /** Approximate maximum summary word count. */
035    private final Integer maxWords;
036    /** Output formatting style for the generated summary. */
037    private final Style summaryStyle;
038    /** Chunk processing method for content that exceeds model token limits. */
039    private final ChunkProcessingMethod chunkProcessingMethod;
040    /** Degree to which generated text follows original wording. */
041    private final ExtractivenessLevel extractivenessLevel;
042
043    private SummaryParams(Builder builder) {
044        this.minWords = builder.minWords;
045        this.maxWords = builder.maxWords;
046        this.summaryStyle = builder.summaryStyle;
047        this.chunkProcessingMethod = builder.chunkProcessingMethod;
048        this.extractivenessLevel = builder.extractivenessLevel;
049    }
050
051    /**
052     * Creates a builder for summarize parameters.
053     *
054     * @return new builder
055     */
056    public static Builder builder() {
057        return new Builder();
058    }
059
060    /**
061     * Returns the approximate minimum word count.
062     *
063     * @return minimum word count, or {@code null} when unset
064     */
065    public Integer getMinWords() {
066        return minWords;
067    }
068
069    /**
070     * Returns the approximate maximum word count.
071     *
072     * @return maximum word count, or {@code null} when unset
073     */
074    public Integer getMaxWords() {
075        return maxWords;
076    }
077
078    /**
079     * Returns the requested summary style.
080     *
081     * @return summary style, or {@code null} when unset
082     */
083    public String getSummaryStyle() {
084        return summaryStyle == null ? null : summaryStyle.getValue();
085    }
086
087    /**
088     * Returns the requested summary style enum.
089     *
090     * @return summary style enum, or {@code null} when unset
091     */
092    @JsonIgnore
093    public Style getSummaryStyleEnum() {
094        return summaryStyle;
095    }
096
097    /**
098     * Returns the chunk processing method.
099     *
100     * @return chunk processing method, or {@code null} when unset
101     */
102    public String getChunkProcessingMethod() {
103        return chunkProcessingMethod == null ? null : chunkProcessingMethod.getValue();
104    }
105
106    /**
107     * Returns the chunk processing method enum.
108     *
109     * @return chunk processing method enum, or {@code null} when unset
110     */
111    @JsonIgnore
112    public ChunkProcessingMethod getChunkProcessingMethodEnum() {
113        return chunkProcessingMethod;
114    }
115
116    /**
117     * Returns the extractiveness level.
118     *
119     * @return extractiveness level, or {@code null} when unset
120     */
121    public String getExtractivenessLevel() {
122        return extractivenessLevel == null ? null : extractivenessLevel.getValue();
123    }
124
125    /**
126     * Returns the extractiveness level enum.
127     *
128     * @return extractiveness level enum, or {@code null} when unset
129     */
130    @JsonIgnore
131    public ExtractivenessLevel getExtractivenessLevelEnum() {
132        return extractivenessLevel;
133    }
134
135    /**
136     * Serializes the parameters using DBMS_CLOUD_AI snake_case JSON names.
137     *
138     * @return JSON representation of this SummaryParams instance
139     */
140    public String toJson() {
141        try {
142            ObjectMapper mapper = new ObjectMapper();
143            mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
144            mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
145            return mapper.writeValueAsString(this);
146        } catch (Exception e) {
147            throw new IllegalStateException("Failed to serialize SummaryParams", e);
148        }
149    }
150
151    /**
152     * Output format style for the generated summary.
153     */
154    public enum Style {
155        /** One or more paragraphs. */
156        PARAGRAPH("paragraph"),
157        /** List of key points. */
158        LIST("list");
159
160        private final String value;
161
162        Style(String value) {
163            this.value = value;
164        }
165
166        /**
167         * Returns the database JSON value.
168         *
169         * @return database JSON value
170         */
171        public String getValue() {
172            return value;
173        }
174    }
175
176    /**
177     * Method used when the source content must be split into chunks.
178     */
179    public enum ChunkProcessingMethod {
180        /** Iteratively refines the summary across chunks. */
181        ITERATIVE_REFINEMENT("iterative_refinement"),
182        /** Summarizes chunks and reduces them into a final summary. */
183        MAP_REDUCE("map_reduce");
184
185        private final String value;
186
187        ChunkProcessingMethod(String value) {
188            this.value = value;
189        }
190
191        /**
192         * Returns the database JSON value.
193         *
194         * @return database JSON value
195         */
196        public String getValue() {
197            return value;
198        }
199    }
200
201    /**
202     * Degree to which the generated summary follows source wording.
203     */
204    public enum ExtractivenessLevel {
205        /** Stays close to original phrasing. */
206        HIGH("high"),
207        /** Balances extraction and paraphrasing. */
208        MEDIUM("medium"),
209        /** Allows more freedom to reword and restructure. */
210        LOW("low");
211
212        private final String value;
213
214        ExtractivenessLevel(String value) {
215            this.value = value;
216        }
217
218        /**
219         * Returns the database JSON value.
220         *
221         * @return database JSON value
222         */
223        public String getValue() {
224            return value;
225        }
226    }
227
228    /**
229     * Builder for {@link SummaryParams}.
230     */
231    public static final class Builder {
232        /** Minimum word count being assembled. */
233        private Integer minWords;
234        /** Maximum word count being assembled. */
235        private Integer maxWords;
236        /** Summary style being assembled. */
237        private Style summaryStyle;
238        /** Chunk processing method being assembled. */
239        private ChunkProcessingMethod chunkProcessingMethod;
240        /** Extractiveness level being assembled. */
241        private ExtractivenessLevel extractivenessLevel;
242
243        private Builder() {
244        }
245
246        /**
247         * Sets the approximate minimum number of words.
248         *
249         * @param minWords minimum word count, greater than or equal to 0
250         * @return this builder instance
251         */
252        public Builder minWords(Integer minWords) {
253            if (minWords != null && minWords < 0) {
254                throw new IllegalArgumentException("minWords must be greater than or equal to 0");
255            }
256            this.minWords = minWords;
257            return this;
258        }
259
260        /**
261         * Sets the approximate maximum number of words.
262         *
263         * @param maxWords maximum word count, greater than or equal to 1
264         * @return this builder instance
265         */
266        public Builder maxWords(Integer maxWords) {
267            if (maxWords != null && maxWords < 1) {
268                throw new IllegalArgumentException("maxWords must be greater than or equal to 1");
269            }
270            this.maxWords = maxWords;
271            return this;
272        }
273
274        /**
275         * Sets the output summary style.
276         *
277         * @param summaryStyle summary style
278         * @return this builder instance
279         */
280        public Builder summaryStyle(Style summaryStyle) {
281            this.summaryStyle = summaryStyle;
282            return this;
283        }
284
285        /**
286         * Sets the chunk processing method.
287         *
288         * @param chunkProcessingMethod chunk processing method
289         * @return this builder instance
290         */
291        public Builder chunkProcessingMethod(ChunkProcessingMethod chunkProcessingMethod) {
292            this.chunkProcessingMethod = chunkProcessingMethod;
293            return this;
294        }
295
296        /**
297         * Sets the extractiveness level.
298         *
299         * @param extractivenessLevel extractiveness level
300         * @return this builder instance
301         */
302        public Builder extractivenessLevel(ExtractivenessLevel extractivenessLevel) {
303            this.extractivenessLevel = extractivenessLevel;
304            return this;
305        }
306
307        /**
308         * Builds immutable summarize parameters.
309         *
310         * @return immutable SummaryParams built from current builder state
311         */
312        public SummaryParams build() {
313            if (minWords != null && maxWords != null && minWords > maxWords) {
314                throw new IllegalArgumentException("minWords must be less than or equal to maxWords");
315            }
316            if (minWords == null && maxWords == null && summaryStyle == null
317                    && chunkProcessingMethod == null && extractivenessLevel == null) {
318                throw new IllegalArgumentException("at least one summarize parameter must be set");
319            }
320            return new SummaryParams(this);
321        }
322    }
323}