agents 1.1.0 copy "agents: ^1.1.0" to clipboard
agents: ^1.1.0 copied to clipboard

Dart port of the Microsoft Agents AI framework. Build, compose, and orchestrate AI agents backed by any ChatClient — with sessions, streaming, tool use, compaction, evaluation, and middleware pipelines.

example/agents_example.dart

// ignore_for_file: avoid_print
/// Demonstrates the core patterns of the agents package.
///
/// [EchoChatClient] is a self-contained stub that echoes user messages back.
/// Replace it with a real ChatClient (e.g. backed by OpenAI, Azure OpenAI,
/// or another provider) to connect to an actual AI model.
library;

import 'dart:io';

import 'package:agents/src/ai/ai_agent_builder.dart';
import 'package:agents/src/ai/chat_client/chat_client_extensions.dart';
import 'package:agents/src/ai/logging_agent.dart';
import 'package:extensions/ai.dart';
import 'package:extensions/logging.dart';
import 'package:extensions/system.dart';

Future<void> main() async {
  // ── 1. Create an agent ──────────────────────────────────────────────────
  //
  // Wrap any ChatClient with asAIAgent(). Swap EchoChatClient for a real
  // provider-backed ChatClient to connect to an LLM.
  final baseAgent = EchoChatClient().asAIAgent(
    name: 'Assistant',
    instructions: 'You are a concise, helpful assistant.',
  );

  // ── 2. Add middleware via AIAgentBuilder ─────────────────────────────────
  //
  // AIAgentBuilder composes decorator agents. Here we add LoggingAgent so
  // every run/runStreaming call is wrapped with structured log output.
  final loggerFactory = NullLoggerFactory.instance;
  final logger = loggerFactory.createLogger('Assistant');

  final agent = AIAgentBuilder(
    innerAgent: baseAgent,
  ).use(agentFactory: (inner) => LoggingAgent(inner, logger)).build();

  // ── 3. Multi-turn conversation with a session ────────────────────────────
  //
  // AgentSession carries chat history across turns automatically.
  print('=== Multi-turn conversation ===');
  final session = await agent.createSession();

  final r1 = await agent.run(
    session,
    null,
    cancellationToken: CancellationToken.none,
    message: 'My name is Ada.',
  );
  print('Assistant: ${r1.text}');

  final r2 = await agent.run(
    session,
    null,
    cancellationToken: CancellationToken.none,
    message: 'What is my name?',
  );
  print('Assistant: ${r2.text}');

  // ── 4. Streaming ─────────────────────────────────────────────────────────
  print('\n=== Streaming ===');
  final streamSession = await agent.createSession();

  stdout.write('Assistant: ');
  await for (final update in agent.runStreaming(
    streamSession,
    null,
    cancellationToken: CancellationToken.none,
    message: 'Count to three.',
  )) {
    stdout.write(update.text);
  }
  stdout.writeln();

  // ── 5. Session serialisation ─────────────────────────────────────────────
  print('\n=== Session serialisation ===');
  final serialised = await agent.serializeSession(session);
  print('Serialised: $serialised');
  final restored = await agent.deserializeSession(serialised);
  print('Restored session type: ${restored.runtimeType}');
}

// ── Stub ChatClient ─────────────────────────────────────────────────────────
//
// EchoChatClient is a minimal ChatClient that echoes the last user message.
// It exists solely so this example compiles and runs without a real API key.
// Replace it with your provider's ChatClient implementation in production.

class EchoChatClient implements ChatClient {
  @override
  Future<ChatResponse> getResponse({
    required Iterable<ChatMessage> messages,
    ChatOptions? options,
    CancellationToken? cancellationToken,
  }) async {
    final reply = _buildReply(messages, options);
    return ChatResponse.fromMessage(
      ChatMessage.fromText(ChatRole.assistant, reply),
    );
  }

  @override
  Stream<ChatResponseUpdate> getStreamingResponse({
    required Iterable<ChatMessage> messages,
    ChatOptions? options,
    CancellationToken? cancellationToken,
  }) async* {
    final reply = _buildReply(messages, options);
    for (final word in reply.split(' ')) {
      yield ChatResponseUpdate.fromText(ChatRole.assistant, '$word ');
    }
  }

  @override
  T? getService<T>({Object? key}) => null;

  @override
  void dispose() {}

  String _buildReply(Iterable<ChatMessage> messages, ChatOptions? options) {
    final system = options?.instructions;
    final last = messages.lastWhere(
      (m) => m.role == ChatRole.user,
      orElse: () => ChatMessage.fromText(ChatRole.user, ''),
    );
    final userText = last.text;
    final prefix = system != null ? '[$system] ' : '';
    return '${prefix}You said: "$userText"';
  }
}
0
likes
150
points
248
downloads

Documentation

API reference

Publisher

verified publisherjamiewest.dev

Weekly Downloads

Dart port of the Microsoft Agents AI framework. Build, compose, and orchestrate AI agents backed by any ChatClient — with sessions, streaming, tool use, compaction, evaluation, and middleware pipelines.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

clock, extensions, file, opentelemetry, path, pool

More

Packages that depend on agents