createModel method
Model
createModel(
- String modelName,
- SchemanticType customOptions
)
Implementation
Model createModel(String modelName, SchemanticType customOptions) {
return Model(
name: '$name/$modelName',
customOptions: customOptions,
metadata: {'model': commonModelInfo.toJson()},
fn: (req, ctx) async {
gcl.GenerationConfig generationConfig;
List<gcl.SafetySetting>? safetySettings;
List<gcl.Tool>? tools;
gcl.ToolConfig? toolConfig;
String? apiKey;
final isJsonMode =
req!.output?.format == 'json' ||
req.output?.contentType == 'application/json';
if (customOptions == GeminiTtsOptions.$schema) {
final options = req.config == null
? GeminiTtsOptions()
: GeminiTtsOptions.$schema.parse(req.config!);
apiKey = options.apiKey;
generationConfig = toGeminiTtsSettings(
options,
req.output?.schema,
isJsonMode,
);
safetySettings = toGeminiSafetySettings(options.safetySettings);
tools = toGeminiTools(
req.tools,
codeExecution: options.codeExecution,
googleSearch: options.googleSearch,
);
toolConfig = toGeminiToolConfig(options.functionCallingConfig);
} else {
final options = req.config == null
? GeminiOptions()
: GeminiOptions.$schema.parse(req.config!);
apiKey = options.apiKey;
generationConfig = toGeminiSettings(
options,
req.output?.schema,
isJsonMode,
);
safetySettings = toGeminiSafetySettings(options.safetySettings);
tools = toGeminiTools(
req.tools,
codeExecution: options.codeExecution,
googleSearch: options.googleSearch,
);
toolConfig = toGeminiToolConfig(options.functionCallingConfig);
}
final service = await getApiClient(apiKey);
try {
final systemMessage = req.messages
.where((m) => m.role == Role.system)
.firstOrNull;
final messages = req.messages
.where((m) => m.role != Role.system)
.toList();
final generateRequest = gcl.GenerateContentRequest(
contents: toGeminiContent(messages),
tools: tools.isEmpty ? null : tools,
toolConfig: toolConfig,
generationConfig: generationConfig,
safetySettings: safetySettings?.isEmpty ?? true
? null
: safetySettings,
systemInstruction: systemMessage == null
? null
: gcl.Content(
parts: systemMessage.content.map(toGeminiPart).toList(),
role: 'system',
),
);
if (ctx.streamingRequested) {
final stream = service.streamGenerateContent(
generateRequest,
model: 'models/$modelName',
);
final chunks = <gcl.GenerateContentResponse>[];
await for (final chunk in stream) {
chunks.add(chunk);
if (chunk.candidates?.isNotEmpty == true) {
final (message, finishReason) = fromGeminiCandidate(
chunk.candidates!.first,
);
ctx.sendChunk(
ModelResponseChunk(index: 0, content: message.content),
);
}
}
final aggregated = aggregateResponses(chunks);
if (aggregated.candidates?.isEmpty ?? true) {
final blockReason = aggregated.promptFeedback?.blockReason;
throw Exception(
'No candidates returned from generative stream. Block reason: $blockReason',
);
}
final (message, finishReason) = fromGeminiCandidate(
aggregated.candidates!.first,
);
return ModelResponse(
finishReason: finishReason,
message: message,
raw: aggregated.toJson(),
usage: extractUsage(aggregated.usageMetadata),
);
} else {
final response = await service.generateContent(
generateRequest,
model: 'models/$modelName',
);
if (response.candidates?.isEmpty ?? true) {
final blockReason = response.promptFeedback?.blockReason;
throw Exception(
'No candidates returned from generateContent. Block reason: $blockReason',
);
}
final (message, finishReason) = fromGeminiCandidate(
response.candidates!.first,
);
return ModelResponse(
finishReason: finishReason,
message: message,
raw: response?.toJson(),
usage: extractUsage(response.usageMetadata),
);
}
} catch (e, stack) {
throw handleException(e, stack);
} finally {
service.client.close();
}
},
);
}