Packages
claude_gleam
1.0.0
Gleam SDK for the Anthropic Claude API with agentic tool-use loop and BEAM concurrency
Current section
Files
Jump to
Current section
Files
src/claude/agent/actor.gleam
import claude/agent.{type AgentError, type AgentEvent, type AgentResult, Started}
import claude/agent/config.{type AgentConfig}
import claude/types/message
import gleam/erlang/process.{type Pid, type Subject}
import gleam/int
import gleam/list
/// Returns the current system time in native time units (typically nanoseconds).
/// Used to generate unique session IDs for each agent run.
@external(erlang, "erlang", "system_time")
fn system_time() -> Int
/// Run the agent loop, calling the provided callback with events at each step.
///
/// This is a synchronous function that blocks until the agent completes.
/// The `on_event` callback is invoked at each notable step, giving the caller
/// visibility into the agent's progress.
///
/// ## Example
///
/// ```gleam
/// actor.run_with_events(config, "Hello", fn(event) {
/// case event {
/// agent.Started(id) -> io.println("Started: " <> id)
/// agent.Done(result) -> io.println("Done!")
/// _ -> Nil
/// }
/// })
/// ```
pub fn run_with_events(
config: AgentConfig,
prompt: String,
on_event: fn(AgentEvent) -> Nil,
) -> Result(AgentResult, AgentError) {
let session_id = "agent-" <> int.to_string(system_time())
on_event(Started(session_id: session_id))
let initial_messages = [message.new_user(prompt)]
agent.event_loop(
config,
list.reverse(initial_messages),
0,
0,
0,
on_event,
)
}
/// Start an agent in a new BEAM process, sending events to the given subject.
///
/// The agent runs asynchronously in a spawned process. Events are sent to
/// the caller's subject as they occur, so the caller can receive them from
/// their mailbox.
///
/// Returns the Pid of the spawned agent process.
///
/// ## Example
///
/// ```gleam
/// let events = process.new_subject()
/// let pid = actor.start(config, "Hello", events)
///
/// // Receive events from the agent
/// case process.receive(events, 30_000) {
/// Ok(agent.Started(id)) -> io.println("Agent started: " <> id)
/// Ok(agent.Done(result)) -> io.println("Agent done!")
/// _ -> io.println("Timeout or other event")
/// }
/// ```
pub fn start(
config: AgentConfig,
prompt: String,
caller: Subject(AgentEvent),
) -> Pid {
process.spawn(fn() {
let _result =
run_with_events(config, prompt, fn(event) {
process.send(caller, event)
})
Nil
})
}