Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/googleai_dart/lib/googleai_dart.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import '../copy_with_sentinel.dart';
import 'thinking_config.dart';

/// Configuration options for model generation.
class GenerationConfig {
Expand Down Expand Up @@ -32,6 +33,9 @@ class GenerationConfig {
/// Response schema (for structured output).
final Map<String, dynamic>? responseSchema;

/// Thinking configuration.
final ThinkingConfig? thinkingConfig;

/// Creates a [GenerationConfig].
const GenerationConfig({
this.candidateCount,
Expand All @@ -44,6 +48,7 @@ class GenerationConfig {
this.frequencyPenalty,
this.responseMimeType,
this.responseSchema,
this.thinkingConfig,
});

/// Creates a [GenerationConfig] from JSON.
Expand All @@ -59,6 +64,12 @@ class GenerationConfig {
frequencyPenalty: (json['frequencyPenalty'] as num?)?.toDouble(),
responseMimeType: json['responseMimeType'] as String?,
responseSchema: json['responseSchema'] as Map<String, dynamic>?,
thinkingConfig:
json['thinkingConfig'] != null
? ThinkingConfig.fromJson(
json['thinkingConfig'] as Map<String, dynamic>,
)
: null,
);

/// Converts to JSON.
Expand All @@ -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.
Expand All @@ -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<String>?,
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<String>?,
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<String, dynamic>?,
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<String, dynamic>?,
thinkingConfig:
thinkingConfig == unsetCopyWithValue
? this.thinkingConfig
: thinkingConfig as ThinkingConfig?,
);
}
}
Original file line number Diff line number Diff line change
@@ -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<String, dynamic> json) {
return ThinkingConfig(
includeThoughts: json['includeThoughts'] as bool?,
thinkingBudget: json['thinkingBudget'] as int?,
thinkingLevel: _thinkingLevelFromString(json['thinkingLevel']),
);
}

Map<String, dynamic> 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';
}
}
}
Loading