diff --git a/packages/googleai_dart/lib/googleai_dart.dart b/packages/googleai_dart/lib/googleai_dart.dart index ac38db14..ce475172 100644 --- a/packages/googleai_dart/lib/googleai_dart.dart +++ b/packages/googleai_dart/lib/googleai_dart.dart @@ -95,6 +95,7 @@ export 'src/models/generation/input_feedback.dart'; export 'src/models/generation/prompt_feedback.dart'; // Models - Generation (additional) export 'src/models/generation/schema.dart'; +export 'src/models/generation/thinking_config.dart'; // Models - Metadata export 'src/models/metadata/finish_reason.dart'; export 'src/models/metadata/modality_token_count.dart'; diff --git a/packages/googleai_dart/lib/src/models/generation/generation_config.dart b/packages/googleai_dart/lib/src/models/generation/generation_config.dart index 4634b36e..b41eb7c6 100644 --- a/packages/googleai_dart/lib/src/models/generation/generation_config.dart +++ b/packages/googleai_dart/lib/src/models/generation/generation_config.dart @@ -1,4 +1,5 @@ import '../copy_with_sentinel.dart'; +import 'thinking_config.dart'; /// Configuration options for model generation. class GenerationConfig { @@ -32,6 +33,9 @@ class GenerationConfig { /// Response schema (for structured output). final Map? responseSchema; + /// Thinking configuration. + final ThinkingConfig? thinkingConfig; + /// Creates a [GenerationConfig]. const GenerationConfig({ this.candidateCount, @@ -44,6 +48,7 @@ class GenerationConfig { this.frequencyPenalty, this.responseMimeType, this.responseSchema, + this.thinkingConfig, }); /// Creates a [GenerationConfig] from JSON. @@ -59,6 +64,12 @@ class GenerationConfig { frequencyPenalty: (json['frequencyPenalty'] as num?)?.toDouble(), responseMimeType: json['responseMimeType'] as String?, responseSchema: json['responseSchema'] as Map?, + thinkingConfig: + json['thinkingConfig'] != null + ? ThinkingConfig.fromJson( + json['thinkingConfig'] as Map, + ) + : null, ); /// Converts to JSON. @@ -73,6 +84,7 @@ class GenerationConfig { if (frequencyPenalty != null) 'frequencyPenalty': frequencyPenalty, if (responseMimeType != null) 'responseMimeType': responseMimeType, if (responseSchema != null) 'responseSchema': responseSchema, + if (thinkingConfig != null) 'thinkingConfig': thinkingConfig!.toJson(), }; /// Creates a copy with replaced values. @@ -87,34 +99,47 @@ class GenerationConfig { Object? frequencyPenalty = unsetCopyWithValue, Object? responseMimeType = unsetCopyWithValue, Object? responseSchema = unsetCopyWithValue, + Object? thinkingConfig = unsetCopyWithValue, }) { return GenerationConfig( - candidateCount: candidateCount == unsetCopyWithValue - ? this.candidateCount - : candidateCount as int?, - stopSequences: stopSequences == unsetCopyWithValue - ? this.stopSequences - : stopSequences as List?, - maxOutputTokens: maxOutputTokens == unsetCopyWithValue - ? this.maxOutputTokens - : maxOutputTokens as int?, - temperature: temperature == unsetCopyWithValue - ? this.temperature - : temperature as double?, + candidateCount: + candidateCount == unsetCopyWithValue + ? this.candidateCount + : candidateCount as int?, + stopSequences: + stopSequences == unsetCopyWithValue + ? this.stopSequences + : stopSequences as List?, + maxOutputTokens: + maxOutputTokens == unsetCopyWithValue + ? this.maxOutputTokens + : maxOutputTokens as int?, + temperature: + temperature == unsetCopyWithValue + ? this.temperature + : temperature as double?, topP: topP == unsetCopyWithValue ? this.topP : topP as double?, topK: topK == unsetCopyWithValue ? this.topK : topK as int?, - presencePenalty: presencePenalty == unsetCopyWithValue - ? this.presencePenalty - : presencePenalty as double?, - frequencyPenalty: frequencyPenalty == unsetCopyWithValue - ? this.frequencyPenalty - : frequencyPenalty as double?, - responseMimeType: responseMimeType == unsetCopyWithValue - ? this.responseMimeType - : responseMimeType as String?, - responseSchema: responseSchema == unsetCopyWithValue - ? this.responseSchema - : responseSchema as Map?, + presencePenalty: + presencePenalty == unsetCopyWithValue + ? this.presencePenalty + : presencePenalty as double?, + frequencyPenalty: + frequencyPenalty == unsetCopyWithValue + ? this.frequencyPenalty + : frequencyPenalty as double?, + responseMimeType: + responseMimeType == unsetCopyWithValue + ? this.responseMimeType + : responseMimeType as String?, + responseSchema: + responseSchema == unsetCopyWithValue + ? this.responseSchema + : responseSchema as Map?, + thinkingConfig: + thinkingConfig == unsetCopyWithValue + ? this.thinkingConfig + : thinkingConfig as ThinkingConfig?, ); } } diff --git a/packages/googleai_dart/lib/src/models/generation/thinking_config.dart b/packages/googleai_dart/lib/src/models/generation/thinking_config.dart new file mode 100644 index 00000000..2e0494bf --- /dev/null +++ b/packages/googleai_dart/lib/src/models/generation/thinking_config.dart @@ -0,0 +1,53 @@ +enum ThinkingLevel { thinkingLevelUnspecified, low, high } + +class ThinkingConfig { + final bool? includeThoughts; + final int? thinkingBudget; + final ThinkingLevel? thinkingLevel; + + ThinkingConfig({ + this.includeThoughts, + this.thinkingBudget, + this.thinkingLevel, + }); + + factory ThinkingConfig.fromJson(Map json) { + return ThinkingConfig( + includeThoughts: json['includeThoughts'] as bool?, + thinkingBudget: json['thinkingBudget'] as int?, + thinkingLevel: _thinkingLevelFromString(json['thinkingLevel']), + ); + } + + Map toJson() { + return { + if (includeThoughts != null) 'includeThoughts': includeThoughts, + if (thinkingBudget != null) 'thinkingBudget': thinkingBudget, + if (thinkingLevel != null) + 'thinkingLevel': _thinkingLevelToString(thinkingLevel!), + }; + } + + static ThinkingLevel? _thinkingLevelFromString(String? value) { + switch (value) { + case 'LOW': + return ThinkingLevel.low; + case 'HIGH': + return ThinkingLevel.high; + case 'THINKING_LEVEL_UNSPECIFIED': + default: + return ThinkingLevel.thinkingLevelUnspecified; + } + } + + static String _thinkingLevelToString(ThinkingLevel level) { + switch (level) { + case ThinkingLevel.low: + return 'LOW'; + case ThinkingLevel.high: + return 'HIGH'; + case ThinkingLevel.thinkingLevelUnspecified: + return 'THINKING_LEVEL_UNSPECIFIED'; + } + } +}