Adam

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN


1.003     2026-03-11 02:08:02Z
        + Administrative update to cleanup the provides for CPAN

1.002     2026-03-08 05:06:55Z
	+ Updated POD: Adam and Moses now document IO::Async support and dual event loop modes
	+ ai-bot example: multi-channel support with per-channel message buffers
	+ ai-bot example: SYSTEM_PROMPT env var for custom system prompt additions
	+ ai-bot example: error messages only shown in main channel
	+ ai-bot example: typing delay now happens BEFORE each line for more human-like output
	+ ai-bot example: info-level logging for all incoming IRC events (public, join, part, quit, PM) with channel/source
	+ Default logger now includes timestamps in [YYYY-MM-DD HH:MM:SS] [level] format
	+ Fixed stray =cut in Adam.pm that hid async() and stop() methods from compilation
	+ Fixed logger timestamps: log_dispatch_conf callback instead of around log

1.001     2026-03-07 19:44:57Z

1.000     2026-03-07 03:12:40Z
	+ Switched to @Author::GETTY Dist::Zilla plugin bundle
	+ Added IO::Async support via ->async() method (requires IO::Async::Loop::POE)
	+ Added ->stop() method for cleanly stopping both POE and IO::Async event loops
	+ Modernized POD documentation to inline format
	+ Added cpanfile for dependency management

Changes  view on Meta::CPAN

	+ Fix a mistake we accidentally released in 0.07

0.07 2010-06-10
	+ Fix _build__irc to pull from the bot configuration (stephan48)
	+ Add RT Plugin example and netcat bot example

0.06  2009-10-30
	+ Moses::Declare
	  MooseX::Declare derived syntax for writing Bots, very experimental.
	+ Adam::Logger
	  Refactor of the logging API so that we can use alternate Logging
	  implementations, ie Log4perl support.

0.05  2009-09-24
	+ Add missing build_requires for Test::Deep

0.04  2009-09-23
	+ Remove dependency on MooseX::AttributeHelpers in favor of Moose's Native::Attributes
	+ Add MooseX::Aliases dependency for nick/nickname
	+ refactor code and clean up generally for release to CPAN

MANIFEST  view on Meta::CPAN

lib/Moses.pm
lib/Moses/Declare.pm
lib/Moses/Declare/Syntax/BotKeyword.pm
lib/Moses/Declare/Syntax/EventKeyword.pm
lib/Moses/Declare/Syntax/PluginKeyword.pm
lib/Moses/Plugin.pm
lib/oses.pm
t/00.load.t
t/01.simple.t
t/02.override.t
t/03.logger.t
t/04.declare.t
t/05.async.t
t/author-pod-syntax.t

META.json  view on Meta::CPAN

               "Dist::Zilla::Plugin::Git::Commit" : {
                  "add_files_in" : [],
                  "commit_msg" : "v%V%n%n%c",
                  "signoff" : 0
               },
               "Dist::Zilla::Role::Git::DirtyFiles" : {
                  "allow_dirty" : [
                     "Changes"
                  ],
                  "allow_dirty_match" : [],
                  "changelog" : "Changes"
               },
               "Dist::Zilla::Role::Git::Repo" : {
                  "git_version" : "2.39.5",
                  "repo_root" : "."
               },
               "Dist::Zilla::Role::Git::StringFormatter" : {
                  "time_zone" : "local"
               }
            },
            "name" : "@Author::GETTY/@Git::VersionManager/release snapshot",
            "version" : "2.052"
         },
         {
            "class" : "Dist::Zilla::Plugin::Git::Tag",
            "config" : {
               "Dist::Zilla::Plugin::Git::Tag" : {
                  "branch" : null,
                  "changelog" : "Changes",
                  "signed" : 0,
                  "tag" : "1.003",
                  "tag_format" : "%v",
                  "tag_message" : "v%V"
               },
               "Dist::Zilla::Role::Git::Repo" : {
                  "git_version" : "2.39.5",
                  "repo_root" : "."
               },
               "Dist::Zilla::Role::Git::StringFormatter" : {

META.json  view on Meta::CPAN

               },
               "Dist::Zilla::Role::Git::DirtyFiles" : {
                  "allow_dirty" : [
                     "Build.PL",
                     "Changes",
                     "Makefile.PL"
                  ],
                  "allow_dirty_match" : [
                     "(?^:^lib/.*\\.pm$)"
                  ],
                  "changelog" : "Changes"
               },
               "Dist::Zilla::Role::Git::Repo" : {
                  "git_version" : "2.39.5",
                  "repo_root" : "."
               },
               "Dist::Zilla::Role::Git::StringFormatter" : {
                  "time_zone" : "local"
               }
            },
            "name" : "@Author::GETTY/@Git::VersionManager/post-release commit",

META.yml  view on Meta::CPAN

      class: Dist::Zilla::Plugin::Git::Commit
      config:
        Dist::Zilla::Plugin::Git::Commit:
          add_files_in: []
          commit_msg: v%V%n%n%c
          signoff: 0
        Dist::Zilla::Role::Git::DirtyFiles:
          allow_dirty:
            - Changes
          allow_dirty_match: []
          changelog: Changes
        Dist::Zilla::Role::Git::Repo:
          git_version: 2.39.5
          repo_root: .
        Dist::Zilla::Role::Git::StringFormatter:
          time_zone: local
      name: '@Author::GETTY/@Git::VersionManager/release snapshot'
      version: '2.052'
    -
      class: Dist::Zilla::Plugin::Git::Tag
      config:
        Dist::Zilla::Plugin::Git::Tag:
          branch: ~
          changelog: Changes
          signed: 0
          tag: '1.003'
          tag_format: '%v'
          tag_message: v%V
        Dist::Zilla::Role::Git::Repo:
          git_version: 2.39.5
          repo_root: .
        Dist::Zilla::Role::Git::StringFormatter:
          time_zone: local
      name: '@Author::GETTY/@Git::VersionManager/Git::Tag'

META.yml  view on Meta::CPAN

          add_files_in: []
          commit_msg: 'increment $VERSION after %v release'
          signoff: 0
        Dist::Zilla::Role::Git::DirtyFiles:
          allow_dirty:
            - Build.PL
            - Changes
            - Makefile.PL
          allow_dirty_match:
            - (?^:^lib/.*\.pm$)
          changelog: Changes
        Dist::Zilla::Role::Git::Repo:
          git_version: 2.39.5
          repo_root: .
        Dist::Zilla::Role::Git::StringFormatter:
          time_zone: local
      name: '@Author::GETTY/@Git::VersionManager/post-release commit'
      version: '2.052'
    -
      class: Dist::Zilla::Plugin::Git::Push
      config:

README.md  view on Meta::CPAN


__PACKAGE__->run unless caller;
```

## Features

- **Declarative syntax** - Simple DSL for bot configuration
- **Plugin system** - Easy to extend with POE::Component::IRC plugins
- **Multiple event loops** - Supports both POE (default) and IO::Async
- **Command-line options** - Built-in support via MooseX::Getopt
- **Logging** - Configurable logging via MooseX::LogDispatch

## IO::Async Support

You can use IO::Async as the event loop (requires IO::Async::Loop::POE):

```perl
package AsyncBot;
use Moses;
use namespace::autoclean;

ex/ai-bot.pl  view on Meta::CPAN

- Silence is your default state. Speaking is the exception.
- You should be silent at LEAST 80% of the time.

HOW TO RESPOND (when you actually should):
- Write plain text. Your messages appear in the channel as-is.
- To address someone, write their nick followed by a colon: Getty: hey there
- Input uses <nick> format but your output is always plain text with nick: format.
- You can address different people on different lines.
- Or say something to the whole channel without any prefix.
- Each newline becomes a separate IRC message with a small delay between them.
- Keep it SHORT. One or two lines is usually enough. This is chat, not a blog.
- NEVER narrate your tool usage in the chat. Tools work silently in the background.
  Don't write things like "*save_note: ...*" or "Let me look that up..." — just do it.

IRC LINE CONSTRAINTS:
- Each line has a hard limit of $MAX_LINE characters. Never exceed this.
- Keep lines short and conversational. This is chat, not email.
- No markdown, no bullet points, no code blocks. Plain text only.
- Shorter is always better. Seriously. Less is more.

PRIVATE MESSAGES:

ex/rt-plugin.pl  view on Meta::CPAN


    has rt => (
        isa        => 'RT::Client::REST',
        is         => 'ro',
        lazy_build => 1,
        handles    => { show_ticket => [ 'show', ( type => 'ticket' ) ] },
    );

    sub _build_rt {
        my $rt = RT::Client::REST->new( server => $_[0]->server );
        $rt->login( username => $_[0]->user, password => $_[0]->pass, );
        return $rt;
    }

    sub ticket {
        my ( $self, $id ) = @_;
        try {
            if ( my $t = $self->show_ticket( id => $id ) ) {
                return "$$t{Status} #${id}: $$t{Subject}";
            }
            return "Ticket $id not found";

lib/Adam.pm  view on Meta::CPAN


use MooseX::Aliases;
use Adam::Logger::Default;

with qw(
  MooseX::SimpleConfig
  MooseX::Getopt
);


has logger => (
    does       => 'Adam::Logger::API',
    is         => 'ro',
    traits     => ['NoGetopt'],
    lazy_build => 1,
    handles    => 'Adam::Logger::API',
);


sub _build_logger { Adam::Logger::Default->new() }

has nickname => (
    isa      => 'Str',
    reader   => 'get_nickname',
    alias    => 'nick',
    traits   => ['Getopt'],
    cmd_flag => 'nickname',
    required => 1,
    builder  => 'default_nickname',
);

lib/Adam.pm  view on Meta::CPAN


The Adam class implements an IRC bot based on L<POE::Component::IRC::State>,
L<Moose>, and L<MooseX::POE>. It supports two event loop modes: the default
L<POE> loop via C<run()>, and an L<IO::Async> mode via C<async()> that allows
integration with other L<IO::Async>-based components through
L<IO::Async::Loop::POE>.

Adam is not meant to be used directly — see L<Moses> for the declarative
sugar layer.

=head2 logger

Logger object that implements the L<Adam::Logger::API> role. Defaults to
L<Adam::Logger::Default>.

=head2 nickname

The IRC nickname for the bot. Defaults to the package name. Required.

=head2 server

lib/Adam/Logger/API.pm  view on Meta::CPAN

package Adam::Logger::API;
# ABSTRACT: API Role for the Adam logger
our $VERSION = '1.003';
use Moose::Role;
use namespace::autoclean;


requires qw(
  log
  debug
  info
  notice
  warning
  error
  critical
  alert
  emergency
);

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Adam::Logger::API - API Role for the Adam logger

=head1 VERSION

version 1.003

=head1 DESCRIPTION

Defines the logging API interface required for Adam bot loggers.

=head1 SUPPORT

=head2 Issues

Please report bugs and feature requests on GitHub at
L<https://github.com/perigrin/adam-bot-framework/issues>.

=head2 IRC

lib/Adam/Logger/Default.pm  view on Meta::CPAN

package Adam::Logger::Default;
# ABSTRACT: Default logger for Adam bots
our $VERSION = '1.003';
use Moose;
use POSIX qw( strftime );


sub log_dispatch_conf {
  return {
    class     => 'Log::Dispatch::Screen',
    min_level => 'debug',
    stderr    => 1,
    callbacks => sub {
      my %p = @_;
      my $ts = strftime('%Y-%m-%d %H:%M:%S', localtime);
      return "[$ts] [$p{level}] $p{message}\n";
    },
  };

lib/Adam/Logger/Default.pm  view on Meta::CPAN

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

Adam::Logger::Default - Default logger for Adam bots

=head1 VERSION

version 1.003

=head1 DESCRIPTION

Default logging implementation for Adam bots using L<MooseX::LogDispatch::Levels>.
Log messages include timestamps in C<[YYYY-MM-DD HH:MM:SS]> format.

=head1 SUPPORT

=head2 Issues

Please report bugs and feature requests on GitHub at
L<https://github.com/perigrin/adam-bot-framework/issues>.

=head2 IRC

lib/Adam/Plugin.pm  view on Meta::CPAN

use Moose;
use namespace::autoclean;


has bot => (
    isa      => 'Adam',
    is       => 'ro',
    required => 1,
    handles  => [
        qw(
          log
          owner
          irc
          yield
          privmsg
          nick
          )
    ],
);


lib/Adam/Plugin.pm  view on Meta::CPAN



sub PCI_unregister {
    my ( $self, $irc ) = @_;
    return 1;
}


sub _default {
    my ( $self, $irc, $event ) = @_;
    $self->log->notice("_default called for $event");
}

1;

__END__

=pod

=encoding UTF-8

lib/Adam/Plugin.pm  view on Meta::CPAN


version 1.003

=head1 DESCRIPTION

The Adam::Plugin class implements a base class for Adam/Moses IRC bot plugins.

=head2 bot

The L<Adam> bot instance. Required. Handles several methods from the bot
including C<log>, C<owner>, C<irc>, C<yield>, C<privmsg>, and C<nick>.

=head2 default_events

The default events that this plugin will listen to. Returns an ArrayRef of all
methods prefixed with C<S_> (server events) or C<U_> (user events) in the current
class.

=head2 PCI_register

Called when the plugin is registered with the IRC component. Automatically



( run in 1.584 second using v1.01-cache-2.11-cpan-5837b0d9d2c )