NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
pub.dev
Unified AI provider integration for Flutter - OpenAI, Google AI, xAI, Android native TTS with consistent API.
Last release 1 years ago
03 Oct 2025
Too new to tell
only 1 release windows
Nearly every release is documented
notes for 20 of 21 stable releases
Nothing withdrawn
no release was ever pulled
1 years old
21 releases · first in 2025
One column per month.
AndroidNativeProvider: Provider completo para TTS y STT nativo en Android
speech_to_text plugin para transcripción en tiempo realOpenAI TTS API Fix: Hardcoded response_format: 'pcm' en OpenAI Provider
response_format: 'pcm' en OpenAI ProviderAIResponse incluyen campo provider identificando el proveedor usadobase64 ahora contiene el M4A convertido (no PCM crudo)AIResponse constructor ahora requiere parámetro provider: StringAIProviderManager'transcription_service' como provider`audioFormat` opcional: Usuario puede elegir entre M4A (default) o MP3 para salida final
audioFormat opcional: Usuario puede elegir entre M4A (default) o MP3 para salida finalaudioFormat, se usa M4A automáticamente (75% menos espacio)audioFormat solo afecta conversión finalAiAudioParams() sin parámetros funciona perfectamenteflutter_audio_toolkit con ffmpeg_kit_flutter_new ^3.2.0_isFFmpegSupported() determina disponibilidad de FFmpeg KitAiAudioFormat.m4a y AiAudioFormat.mp3 constantes disponiblesaudioFormatAI.listen() ahora retorna Future<AIResponse?>
Future<AIResponse?>:
autoStop=true (default): retorna AIResponse con transcripción completaautoStop=false: retorna null inmediatamente (solo inicia grabación)AIResponse(text: '') vacíoautoStopAudioTranscriptionService.recordAndTranscribe(): Retorna null cuando autoStop=falseAI.stopListen() para obtener resultado con control manualAIContext → AISystemPrompt: Renombrado clase principal para reflejar correctamente que todos los providers soportan system prompts
ai_context.dart → ai_system_prompt.dartAIResponse con transcripción Y audio grabado (URL + base64)Future<String?> a Future<AIResponse?> para consistenciaresponse.text - Transcripción del audioresponse.audio?.url - Ruta del archivo de audio grabado en cachéresponse.audio?.base64 - Audio en base64 para envío directoresponse.audio?.durationMs - Duración de la grabaciónresponse.audio?.transcript - Mismo contenido que textvoice añadido a sendMessage() en BaseProvider_selectVoice() y getVoiceForRequest()imageParams y audioParams en AdditionalParamsrole: system en messages (OpenAI compatible)systemInstruction field nativo (no en messages)role: system en messages array (formato estándar)profile.toJson() en lugar de pasar objetos directamente_createAIResponseWithAudio() para generar respuestas completas// ❌ ANTES (v1.5.x)
final aiContext = AIContext(context: profile, ...);
await AI.text(prompt, aiContext);
// Para audio:
final transcript = await AI.listen(); // Solo String
final stopped = await AI.stopListen(); // Solo String?
// ✅ AHORA (v1.6.0)
final systemPrompt = AISystemPrompt(context: profile, ...);
await AI.text(prompt, systemPrompt);
// Para audio con datos completos:
final response = await AI.listen(); // AIResponse completo
print(response.text); // Transcripción
print(response.audio?.url); // Archivo de audio
print(response.audio?.base64); // Audio en base64
final stopped = await AI.stopListen(); // AIResponse? completo
AiImageParams.seed → sourceImageBase64: Campo seed completamente removido y reemplazado por sourceImageBase64 para edición de imágenes
seed completamente removido y reemplazado por sourceImageBase64 para edición de imágenesseed de respuestas de providersseedjson_utils.dart con parsing inteligente de JSON, markdown y texto mixto{"description": "...", "response": "..."} para mejor parsingaiContext.toJson() correctamente// ❌ ANTES (v1.4.x)
const params = AiImageParams(
seed: 'resp_abc123', // Para reutilizar respuesta
quality: AiImageQuality.high,
);
// ✅ AHORA (v1.5.0)
const params = AiImageParams(
sourceImageBase64: 'data:image/png;base64,...', // Para editar imagen
quality: AiImageQuality.high,
);
input_image en la API de Responsesinline_data para contexto de ediciónextractJsonBlock() con balanceado de llaves y detección de markdownAIResponse renovado: Cambio de propiedades planas a objetos tipados estructurados
AiImage y AiAudio con campos específicos y metadatos completosseed, url, prompt, base64, createdAtMsurl, transcript, base64, durationMs, isAutoTtstext, image?, audio?// ❌ Antes (1.4.2)
final response = await AI.image('Un gato');
final fileName = response.imageFileName;
final base64 = response.imageBase64;
// ✅ Ahora (1.4.3)
final response = await AI.image('Un gato');
final fileName = response.image?.url;
final base64 = response.image?.base64;
Sin breaking changes: API pública permanece inalterada
aiContext.historyAI.text() hasta provider funciona correctamenteList<Map<String, dynamic>> para historySin breaking changes: La API pública permanece igual
history duplicado en providersaiContext.historyaiContext.history directamentesendMessage sin parámetro history duplicadoModelo renombrado: AISystemPrompt → AIContext para mayor claridad conceptual
AISystemPrompt → AIContext para mayor claridad conceptualai_system_prompt.dart → ai_context.dartsystemPrompt → aiContext en APIs de funcionesimport 'package:ai_providers/ai_providers.dart' sigue funcionando (re-exportado)aiContext.history directamente en lugar de generar historia falsacontext (propiedad del modelo) y aiContext (parámetro de función)BuildContext de Flutter// ANTES (v1.3.x)
final systemPrompt = AISystemPrompt(context: profile, ...);
await AI.text(prompt, systemPrompt);
// AHORA (v1.4.0+)
final aiContext = AIContext(context: profile, ...);
await AI.text(prompt, aiContext);
ApiKeyManager inteligente: Elimina rotación inútil de API keys cuando solo hay una configurada
markCurrentKeyFailed() y markCurrentKeyExhausted() ahora devuelven boolflutter_secure_storage: Eliminada dependencia innecesaria que no se usaba en el código`AiAudioParams.audioFormat` con valor por defecto: Ahora es String (no nullable) con valor por defecto 'pcm'
AiAudioParams.audioFormat con valor por defecto: Ahora es String (no nullable) con valor por defecto 'pcm'AiAudioParams() sin parámetros funciona perfectamente para casos comunesaudioFormat cambió de String? a String con valor por defecto 'pcm'Eliminado `TranscribeInstructions`: Simplificamos la arquitectura de audio eliminando la clase TranscribeInstructions que tenía características no uti
TranscribeInstructions: Simplificamos la arquitectura de audio eliminando la clase TranscribeInstructions que tenía características no utilizadas (anti-hallucination). Ahora AI.listen() usa directamente AIContext.AiAudioParams clarificado: La documentación ahora especifica claramente que AiAudioParams es exclusivamente para síntesis de voz (TTS) con AI.speak(), no para transcripción.audio_demo_screen.dart ahora usa AiAudioParams en lugar de las obsoletas SynthesizeInstructions.AI.listen() y AI.transcribe() ahora reciben solo AIContextAIContext directamente en transcripciónAiAudioParams ahora documenta correctamente solo parámetros TTS reales soportados por cada proveedorAiAudioParams vs AIContextAiAudioParams`AiImageParams` tipado: AI.image() ahora expone un tercer argumento opcional con constantes (AiImageAspectRatio, AiImageFormat, AiImageQuality, etc.)
AiImageParams tipado: AI.image() ahora expone un tercer argumento opcional con constantes (AiImageAspectRatio, AiImageFormat, AiImageQuality, etc.) para configurar formato, fondo, fidelidad y seeds sin strings mágicos.aspectRatio se mapea internamente a los tamaños recomendados (1024x1024, 1024x1536, 1536x1024) y el seed reutiliza respuestas anteriores si empieza por resp_.AI.image().AiImageParams añadida en comentarios del código fuenteCompatibilidad mantenida con ProviderConfig interno (sin breaking changes en configuración YAML)
getAvailableProviders() actualizada: Ahora devuelve List<AIProvider> en lugar de List<Map<String, dynamic>>provider.id, provider.displayName, provider.description, etc.provider['id'] debe cambiar a provider.idAIProvider class con propiedades: id, displayName, description, capabilities, enabledAIProvider.fromConfig() para conversión desde configuración YAMLAIProvider.empty() para casos de error o fallbacksupportsCapability() para verificar soporte de capacidadesProviderConfig interno (sin breaking changes en configuración YAML)Antes (v1.2.1 y anteriores):
final providers = AI.getAvailableProviders(AICapability.textGeneration);
for (final provider in providers) {
print('${provider['displayName']}: ${provider['description']}');
if (provider['enabled'] == true) {
// usar provider['id']
}
}
Después (v1.2.2+):
final providers = AI.getAvailableProviders(AICapability.textGeneration);
for (final provider in providers) {
print('${provider.displayName}: ${provider.description}');
if (provider.enabled) {
// usar provider.id
}
}
/example con la nueva APIACTUALIZACIÓN A MPL-2.0: Cambio de CC BY-NC-ND 4.0 a Mozilla Public License 2.0
PUNTAJE PERFECTO PUB.DEV: Obtenido el máximo 160/160 puntos en análisis de pub.dev
ai_provider_config.dart, ai_provider_metadata.dart, retry_config.dartAI.*Nothing published for this version
Campo license explícito agregado en pubspec.yaml
API facade unificada con AI.text(), AI.image(), AI.speak(), AI.listen()
AI.text(), AI.image(), AI.speak(), AI.listen()### Agregado - Versión inicial
Your coding agent can read these notes before it upgrades. Set up the MCP server →