NAME

Langertha::Raider::CLI::Runner - Internal runner of one raider CLI prompt, for a human or a machine

VERSION

version 0.504

SYNOPSIS

# Internal to Langertha-Raider -- no API promise.
my $runner = Langertha::Raider::CLI::Runner->new(app => $app, output => $out);
my $ok = $runner->run_prompt('Summarize README.md');
$ok = $runner->run_prompt('Summarize README.md', machine => $machine);

DESCRIPTION

Internal module. Its interface may change without notice.

Runs one prompt through "run_prompt" in Langertha::Raider::Application, which records the run in the session journal, and renders the outcome: the agent's answer plus a status line (elapsed seconds, history size against the context budget, token usage when tracing), or with a machine (Langertha::Raider::CLI::Machine) the run's document -- and, when that machine streams, the run.started, run.state, message and tool events the application hands it. It also owns the signals of a run.

app

The Langertha::Raider::CLI to run on. Required.

output

The Langertha::Raider::CLI::Output to print to. Required.

err

Filehandle for warnings that must not end up in machine output (a session journal that cannot be written). Defaults to STDERR.

run_prompt

my $ok = $runner->run_prompt($text, machine => $machine, session => $session, catch_signals => 1);

Returns true when the run finished, false when it failed (the error is printed, or with machine is the failed document). An empty prompt runs nothing and counts as finished.

With a session (Langertha::Raider::Session) the application records the run in its journal ("run_prompt" in Langertha::Raider::Application), also when it failed or was interrupted; a machine document then names the session in session (id, path). A journal write that fails is a warning ("journal_error"); the run goes on.

notification, reminders and wait_background go to the application as they are (ADR 0027: a turn that delivers notifications of background subagents, notifications in front of the prompt, a run that waits for its background subagents before it ends -- "run_prompt" in Langertha::Raider::Application); a one-shot run passes wait_background.

With catch_signals, a SIGINT during the run cancels it ("cancel_run"): it ends as cancelled at its next safe point, its outcome is printed or written as always, and then the process dies of SIGINT ("die_of_signal"). A second SIGINT while it is being cancelled, one before the application started the run, and a SIGTERM end it as interrupted: see "interrupt".

The options of one run ("run_options": allow_rules, allow_source, model, attach_reads -- a /name run request, "slash_run_request" in Langertha::Raider::Application) go to the application's run as they are; they hold for that run only ("begin_run" in Langertha::Raider::Application).

run_options

The keys of a run request that "run_prompt" hands on: allow_rules allow_source model attach_reads.

interrupt

$runner->interrupt(TERM => $machine, $elapsed);

Ends a run interrupted by the signal: ends the tool subprocesses still running ("terminate_children"), ends the application's run as interrupted (with the signal), prints a note, or with a machine writes the interrupted document, then dies of that same signal through "die_of_signal".

With a machine it also works as a class method, which Langertha::Raider::CLI::Main uses for a signal during startup, before there is an app to run: the stream then has no run.started, only the interrupted state change and run.finished.

cancel_run

my $cancelling = $runner->cancel_run;
my $cancelling = $runner->cancel_run( reason => 'signal' );

Cancels the run in progress without leaving the process -- the REPL's first Ctrl-C, and the first SIGINT of a one-shot run: asks the application to cancel it ("cancel_run" in Langertha::Raider::Application), then ends the tool subprocesses still running ("terminate_children") -- except the background shells of bash ("background_pids" in Langertha::Raider::BashTools), which belong to the session, not to the run. The run ends as cancelled at its next safe point and "run_prompt" returns false, after turn cancelled (or with a machine, the cancelled document). reason is the document's reason (default user_cancel); the first SIGINT of a one-shot run gives signal. Only records and signals, so the signal handler calls it. Returns false when no run is in progress.

abandon

$runner->abandon('TERM');

Ends the run in progress, if there is one, as interrupted by the signal -- its run.finished in the session journal, and with a machine its document -- without leaving the process. The REPL calls it when it is left during a run.

event

$runner->event('tool.call', call => 'c1', name => 'bash', arguments => { ... });

One event of the run in progress, as the application hands it on: into the machine stream ("event" in Langertha::Raider::CLI::Machine), except the user's own input -- a stream message is the agent's (ADR 0013). Without a machine stream, a hook.message (a hook's systemMessage, error or stop, ADR 0022) is printed as a meta line. Outside a run it does nothing.

record

$runner->record($session, 'history.cleared');

Appends one event outside a run to the session journal ("record" in Langertha::Raider::Application). A write that fails is a warning ("journal_error") and returns false.

journal_error

$runner->journal_error($session, $error);

Reports a session journal that cannot be written on "err", warning: session ID not fully saved: ...: the application's "on_journal_error" in Langertha::Raider::Application, which reports only the first failure of a run.

die_of_signal

$runner->die_of_signal('TERM');

Ends the process by the signal, restored to its default action: the parent sees a process killed by that signal (a shell reports 130 for INT, 143 for TERM; the Hall records the raider as signaled). Should the process survive it, it exits with 128 plus the signal number.

terminate_children

$runner->terminate_children;

Ends the processes this raider started that still run -- a bash command (Langertha::Raider::BashTools puts it into a process group of its own, so a signal aimed at raider alone never reaches it), a perl_eval or perl_cpanm child: SIGTERM to each child's process group, or to the child when it leads none, and SIGKILL to what is left after terminate_grace seconds. keep names process IDs to leave alone.

child_pids

The process IDs of this process's children, from /proc, or from ps where there is none.

elapsed_since

my $elapsed = $runner->elapsed_since($t0);

Seconds since the Time::HiRes time $t0, to the millisecond: the elapsed of a document.

SEE ALSO

SUPPORT

Issues

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

IRC

Join #langertha on irc.perl.org or message Getty directly.

CONTRIBUTING

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

AUTHOR

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

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.

https://raudssus.de/