genkit_openai 0.2.2 copy "genkit_openai: ^0.2.2" to clipboard
genkit_openai: ^0.2.2 copied to clipboard

OpenAI plugin for Genkit Dart, provides seamless model integration, generative AI capabilities, and tooling support.

example/example.dart

// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import 'dart:io';
import 'dart:math';

import 'package:genkit/genkit.dart';
import 'package:genkit_openai/genkit_openai.dart';
import 'package:schemantic/schemantic.dart';

part 'example.g.dart';

@Schema()
abstract class $WeatherFlowInput {
  /// Natural language weather query, e.g. "What's the weather in Boston?"
  String get prompt;
}

@Schema()
abstract class $WeatherToolInput {
  /// City name or coordinates to look up
  String get location;

  /// Temperature unit - 'celsius' or 'fahrenheit'
  @StringField(enumValues: ['celsius', 'fahrenheit'])
  String? get unit;
}

@Schema()
abstract class $WeatherToolOutput {
  double get temperature;
  String get condition;
  String get unit;
  int? get humidity;
}

@Schema()
abstract class $MovieReviewInput {
  /// Title of the movie to review
  String get title;

  /// Optional release year to disambiguate
  int? get year;
}

@Schema()
abstract class $MovieReview {
  /// Official movie title
  String get title;

  /// Rating from 1.0 to 10.0
  double get rating;

  /// One-paragraph summary of the film
  String get summary;

  /// List of standout positives
  List<String> get pros;

  /// List of notable negatives
  List<String> get cons;

  /// Recommended audience, e.g. "sci-fi fans", "families"
  String get recommendedFor;
}

/// Defines a flow that demonstrates basic text generation with an OpenAI model.
Flow<String, String, void, void> defineSimpleGenerationFlow(Genkit ai) {
  return ai.defineFlow(
    name: 'simpleGeneration',
    inputSchema: .string(
      defaultValue: 'Tell me a joke about Dart programming.',
    ),
    outputSchema: .string(),
    fn: (prompt, _) async {
      final response = await ai.generate(
        model: openAI.model('gpt-4o-mini'),
        prompt: prompt,
      );
      return response.text;
    },
  );
}

/// Defines a flow that demonstrates real-time token streaming from OpenAI.
Flow<String, String, String, void> defineStreamedSimpleGenerationFlow(
  Genkit ai,
) {
  return ai.defineFlow(
    name: 'streamedSimpleGeneration',
    inputSchema: .string(
      defaultValue: 'Tell me a joke about Dart programming.',
    ),
    outputSchema: .string(),
    streamSchema: .string(),
    fn: (prompt, ctx) async {
      final stream = ai.generateStream(
        model: openAI.model('gpt-4o-mini'),
        prompt: prompt,
      );

      await for (final chunk in stream) {
        if (ctx.streamingRequested) {
          ctx.sendChunk(chunk.text);
        }
      }

      return (await stream.onResult).text;
    },
  );
}

/// Defines a flow that resolves a named OpenAI model from the Genkit registry.
Flow<String, String, void, void> defineModelResolutionFlow(Genkit ai) {
  return ai.defineFlow(
    name: 'modelResolution',
    inputSchema: .string(defaultValue: 'gpt-4o-mini'),
    outputSchema: .string(),
    fn: (modelName, _) async {
      final action = await ai.registry.lookupAction(
        'model',
        'openai/$modelName',
      );

      if (action == null) {
        return 'Model not found: openai/$modelName';
      }

      return [
        'name: ${action.name}',
        'actionType: ${action.actionType}',
        'metadata: ${action.metadata}',
      ].join('\n');
    },
  );
}

/// Defines a flow that lists all models registered by the OpenAI plugin.
Flow<String, String, void, void> defineModelListFlow(Genkit ai) {
  return ai.defineFlow(
    name: 'modelList',
    inputSchema: .string(),
    outputSchema: .string(),
    fn: (_, _) async {
      final actions = await ai.registry.listActions();
      final models = actions
          .where((a) => a.actionType == 'model')
          .map((a) => a.name)
          .toList();

      return models.join('\n');
    },
  );
}

/// Defines a flow that demonstrates OpenAI tool/function calling.
Flow<WeatherFlowInput, String, void, void> defineToolCallingFlow(
  Genkit ai,
  Tool getWeather,
) {
  return ai.defineFlow(
    name: 'toolCalling',
    inputSchema: WeatherFlowInput.$schema,
    outputSchema: .string(),
    fn: (input, _) async {
      final response = await ai.generate(
        model: openAI.model('gpt-4o-mini'),
        prompt: input.prompt,
        toolNames: [getWeather.name],
      );
      return response.text;
    },
  );
}

/// Defines a flow that demonstrates streaming tool/function calling.
Flow<WeatherFlowInput, String, String, void> defineStreamedToolCallingFlow(
  Genkit ai,
  Tool getWeather,
) {
  return ai.defineFlow(
    name: 'streamedToolCalling',
    inputSchema: WeatherFlowInput.$schema,
    outputSchema: .string(),
    streamSchema: .string(),
    fn: (input, ctx) async {
      final stream = ai.generateStream(
        model: openAI.model('gpt-4o-mini'),
        prompt: input.prompt,
        toolNames: [getWeather.name],
      );

      await for (final chunk in stream) {
        if (ctx.streamingRequested) {
          ctx.sendChunk(chunk.text);
        }
      }

      return (await stream.onResult).text;
    },
  );
}

/// Defines a flow that demonstrates structured output with an OpenAI model.
Flow<MovieReviewInput, MovieReview, void, void> defineStructuredOutputFlow(
  Genkit ai,
) {
  return ai.defineFlow(
    name: 'structuredOutput',
    inputSchema: MovieReviewInput.$schema,
    outputSchema: MovieReview.$schema,
    fn: (input, _) async {
      final yearClause = input.year != null ? ' (${input.year})' : '';

      final response = await ai.generate(
        model: openAI.model('gpt-4o'),
        prompt:
            'Write a detailed review of the movie "${input.title}$yearClause".',
        outputFormat: 'json',
        outputSchema: MovieReview.$schema,
      );

      final output = response.output;
      if (output == null) {
        throw StateError('Model returned no structured output.');
      }
      return output;
    },
  );
}

/// Defines a flow that demonstrates streaming structured output.
Flow<MovieReviewInput, MovieReview, String, void>
defineStreamedStructuredOutputFlow(Genkit ai) {
  return ai.defineFlow(
    name: 'streamedStructuredOutput',
    inputSchema: MovieReviewInput.$schema,
    outputSchema: MovieReview.$schema,
    streamSchema: .string(),
    fn: (input, ctx) async {
      final yearClause = input.year != null ? ' (${input.year})' : '';
      final stream = ai.generateStream(
        model: openAI.model('gpt-4o'),
        prompt:
            'Write a detailed review of the movie "${input.title}$yearClause".',
        outputFormat: 'json',
        outputSchema: MovieReview.$schema,
      );

      await for (final chunk in stream) {
        if (ctx.streamingRequested && chunk.text.isNotEmpty) {
          ctx.sendChunk(chunk.text);
        }
      }

      final response = await stream.onResult;
      final output = response.output;
      if (output == null) {
        throw StateError('Model returned no structured output.');
      }
      return output;
    },
  );
}

void main() {
  final ai = Genkit(
    plugins: [openAI(apiKey: Platform.environment['OPENAI_API_KEY'])],
  );

  final getWeather = ai.defineTool(
    name: 'getWeather',
    description:
        'Get the current weather for a specific location. Returns temperature and conditions.',
    inputSchema: WeatherToolInput.$schema,
    outputSchema: WeatherToolOutput.$schema,
    fn: (input, _) async {
      final unit = input.unit ?? 'celsius';
      final random = Random();
      final tempCelsius = 15 + random.nextInt(20);
      final temperature = unit == 'fahrenheit'
          ? (tempCelsius * 9 / 5) + 32
          : tempCelsius.toDouble();
      final conditions = ['sunny', 'cloudy', 'rainy', 'partly cloudy'];

      return WeatherToolOutput(
        temperature: temperature,
        condition: conditions[random.nextInt(conditions.length)],
        unit: unit,
        humidity: 50 + random.nextInt(30),
      );
    },
  );

  defineSimpleGenerationFlow(ai);
  defineStreamedSimpleGenerationFlow(ai);
  defineModelResolutionFlow(ai);
  defineModelListFlow(ai);
  defineToolCallingFlow(ai, getWeather);
  defineStreamedToolCallingFlow(ai, getWeather);
  defineStructuredOutputFlow(ai);
  defineStreamedStructuredOutputFlow(ai);
}
0
likes
160
points
630
downloads

Publisher

verified publishergenkit.dev

Weekly Downloads

OpenAI plugin for Genkit Dart, provides seamless model integration, generative AI capabilities, and tooling support.

Repository (GitHub)
View/report issues
Contributing

Documentation

API reference

License

Apache-2.0 (license)

Dependencies

genkit, json_schema_builder, meta, openai_dart, schemantic

More

Packages that depend on genkit_openai