NAME

Langertha::Role::Chat - Role for APIs with normal chat functionality

VERSION

version 0.100

SYNOPSIS

# Synchronous chat
my $response = $engine->simple_chat('Hello, how are you?');

# Streaming with callback
$engine->simple_chat_stream(sub {
  my ($chunk) = @_;
  print $chunk->content;
}, 'Tell me a story');

# Streaming with iterator
my $stream = $engine->simple_chat_stream_iterator('Tell me a story');
while (my $chunk = $stream->next) {
  print $chunk->content;
}

# Async with Future (traditional style)
my $future = $engine->simple_chat_f('Hello');
my $response = $future->get;

# Async with Future::AsyncAwait (recommended)
use Future::AsyncAwait;

async sub chat_example {
  my ($engine) = @_;
  my $response = await $engine->simple_chat_f('Hello');
  say $response;
}

# Async streaming with Future::AsyncAwait
async sub stream_example {
  my ($engine) = @_;
  my ($content, $chunks) = await $engine->simple_chat_stream_realtime_f(
    sub { print shift->content },
    'Tell me a story'
  );
  say "\nTotal chunks: ", scalar @$chunks;
}

DESCRIPTION

This role provides chat functionality for LLM engines. It includes both synchronous and asynchronous (Future-based) methods for chat and streaming.

simple_chat

my $response = $engine->simple_chat(@messages);

Sends a chat request and returns the response content. Blocks until complete.

simple_chat_stream

my $content = $engine->simple_chat_stream($callback, @messages);

Sends a streaming chat request. Calls $callback with each chunk as it arrives. Returns the complete content when done. Blocks until complete.

simple_chat_stream_iterator

my $stream = $engine->simple_chat_stream_iterator(@messages);

Returns a Langertha::Stream iterator object. Blocks while fetching, then allows iteration over chunks.

simple_chat_f

# Traditional Future style
my $future = $engine->simple_chat_f(@messages);
my $response = $future->get;

# With async/await (recommended)
use Future::AsyncAwait;
async sub my_chat {
  my $response = await $engine->simple_chat_f(@messages);
  return $response;
}

Async version of simple_chat. Returns a Future that resolves to the response content. Implemented using Future::AsyncAwait for clean async/await syntax.

simple_chat_stream_f

my $future = $engine->simple_chat_stream_f(@messages);
my ($content, $chunks) = $future->get;

Async streaming without real-time callback. Returns a Future that resolves to the complete content and an arrayref of all chunks.

simple_chat_stream_realtime_f

# Traditional Future style
my $future = $engine->simple_chat_stream_realtime_f($callback, @messages);
my ($content, $chunks) = $future->get;

# With async/await (recommended)
use Future::AsyncAwait;
async sub my_stream {
  my ($content, $chunks) = await $engine->simple_chat_stream_realtime_f(
    sub { print shift->content },  # Real-time callback
    @messages
  );
  return $content;
}

Async streaming with real-time callback. The $callback is called with each Langertha::Stream::Chunk as it arrives from the server. Returns a Future that resolves to the complete content and all chunks.

This is the recommended method for real-time streaming in async applications. Implemented using Future::AsyncAwait for clean async/await syntax.

ASYNC IMPLEMENTATION

The Future-based methods are implemented using Future::AsyncAwait, which provides clean async/await syntax. Internally, they use IO::Async and Net::Async::HTTP for non-blocking I/O. These modules are loaded lazily only when you call one of the _f methods, so synchronous usage doesn't require them.

All _f methods are defined with async sub, allowing you to use await when calling them from your own async subroutines.

Integration with Mojolicious

For Mojolicious applications, use Future::Mojo to bridge the event loops:

use Future::Mojo;
use Langertha::Engine::OpenAI;

my $engine = Langertha::Engine::OpenAI->new(...);

# Get the Future and use it with Mojo
my $future = $engine->simple_chat_stream_realtime_f(
  sub { print shift->content },
  'Hello!'
);

$future->on_done(sub {
  my ($content, $chunks) = @_;
  # Handle completion
});

# Run the IO::Async loop (or integrate with Mojo::IOLoop)
$engine->_async_loop->run;

SUPPORT

Issues

Please report bugs and feature requests on GitHub at https://github.com/Getty/langertha/issues.

CONTRIBUTING

Contributions are welcome! Please fork the repository and submit a pull request.

AUTHOR

Torsten Raudssus <torsten@raudssus.de> https://raudss.us/

COPYRIGHT AND LICENSE

This software is copyright (c) 2026 by Torsten Raudssus.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.