feat(infinity-agent-core)!: high-level agent system API; migrate daemon + lambda onto it - #92
Draft
shadaj wants to merge 1 commit into
Draft
feat(infinity-agent-core)!: high-level agent system API; migrate daemon + lambda onto it#92shadaj wants to merge 1 commit into
shadaj wants to merge 1 commit into
Conversation
shadaj
added a commit
that referenced
this pull request
Aug 4, 2026
…on + lambda onto it
Introduce `infinity_agent_core::system`, a builder-based, object-oriented API for
running agents, and rebuild both production embeddings on top of it. The docs for
`infinity-runtime` are rewritten around the new API.
Core (`infinity_agent_core::system`):
- `AgentSystemBuilder`: two construction modes — `new(stores, model, sender)` builds a
step-mode `AgentSystem` for serverless platforms; `new_local(stores, model)` builds a
`LocalAgentSystem` with an internal in-process queue (`ChannelSender`).
- `Thread`: loads one conversation thread from the stores; `step(inputs, observer,
cancel_rx)` runs one slice (prepare → completion → history sync → observer commit
barrier → tool dispatch). Per-thread configuration is resolved lazily on first step so
loading a thread never boots tool servers.
- `LocalAgentSystem::start` runs a full actor-system-style runtime: a router plus one
driver task per active thread, with input batching, `<interrupt>` handling for user
text during a completion, deferral of subscription events while a non-passive tool
call is pending, auto-compaction above 75% of the context window, and race-free idle
exit/respawn. `RunningSystem` exposes `sender()`, `send_user_text`, ack'd
`subscribe`, `active_threads`, a `thread_exits` channel for per-conversation resource
teardown, and `begin_shutdown` for process exit. The system itself runs for the
process lifetime.
- `ThreadHandle`: `LocalAgentSystem::start_with_handles()` runs the system with a
built-in channel-based observer (`HandleObserver`) whose subscriber registry is
shared across driver respawns; `RunningSystem::thread_handle(thread_id)` then
attaches to a thread (creating its subscription even before the thread exists) and
returns a handle with `replay()` for the initial snapshot, an unbounded `events`
queue of `AgentEvent`s (exactly-once relative to the replay), and
`send_user_text`/`send` for input.
- `ThreadObserver`: synchronous `on_event(AgentEvent)` fan-out (exactly-once relative
to `on_subscribe` replay snapshots) plus awaited durability hooks
(`on_user_choice_required`/`_dismissed`, `on_commit` before tool dispatch).
- `ModelSource` (per-round model resolution; enables mid-session model switching) with
`StaticModel`; `ThreadConfigSource` (per-thread tools/prompt/notifier; enables
per-session RAP servers) with `StaticThreadConfig`; `DeferQueue` with
`InMemoryDeferQueue`/`NoDeferral`.
- `AgentEvent`/`ReplaySnapshot`/`UserChoice` display types; `Tool::is_passive()`;
in-memory `ConversationStore`/`StateStore` implementations in
`infinity_agent_core::stores`; tokio-backed sleep tools moved into the core
(`with_tokio_sleep_tools`).
- The core API is platform-neutral: `input_queue_arn` is removed from `ToolContext`
and the builder. Platform-specific configuration lives on the tools that need it
(the Lambda sleep tools now carry the input queue ARN as a field, alongside their
scheduler client, role ARN, and delay queue URL).
- All 20 daemon agent-loop tests migrated into core `system/tests.rs` with
byte-identical snapshots, plus 3 new `ThreadHandle` tests (send/receive + late
replay, survival across idle/respawn, dropped-handle pruning).
Daemon (`infinity-daemon`):
- One daemon-lifetime agent system replaces per-session agent loops. Sessions are root
threads; a `thread_exits` watcher marks sessions idle and shuts down their RAP
servers when no keep-alive client is attached.
- New `rap_servers.rs`: `ManagedRapServer`/`ManagedRapTool`/`SessionRapManager` — RAP
servers boot lazily per session via `ThreadConfigSource` and reboot transparently
after idle shutdown. Config-source info messages ("Using local config", etc.) are
preserved at first resolve.
- `DaemonObserver` implements the observer hooks (usage persistence, pending user
choices, live-attach replay including mid-stream thinking).
- `CatalogModelSource` resolves each thread's persisted model selection per round.
- Deleted: `session/thread_worker.rs`, `session/agent_loop.rs`, `sleep_tools.rs`,
`InMemoryMessageSender`, `Session`, `spawn_session`, `AgentMessage`.
Lambda (`infinity-agent-lambda`): event handler rewritten on
`AgentSystemBuilder::new(...).build()` + `thread()`/`filter_deferrable`/`step` with an
`EventCollector`, replacing the hand-rolled `process_batch` plumbing.
Docs (`docs/docs/infinity-runtime`): the single "Rust API" page is replaced by two
sections. "The Agent System API" (overview, building-a-system, running-locally,
step-mode, observers) documents the new high-level API — including thread handles —
and the patterns both embeddings use; "The Low-Level API" (overview, history-manager,
completion-loop) documents the platform traits and loop pieces underneath and when to
use them. Cross-references across overview/architecture/built-in-tools/
deploying-on-lambda updated.
BREAKING CHANGE: `infinity-daemon` no longer exports `sleep_tools`, `AgentMessage`,
`thread_worker`, `agent_loop`, `Session`, or `InMemoryMessageSender`; `SessionManager`'s
API is reshaped around the single agent system and `SharedSessionManager` is now
`Rc<tokio::Mutex<...>>`. In `infinity-agent-core`, builder tools are stored as
`Rc<dyn Tool<M>>`, `Tool` gains a defaulted `is_passive` method, `ToolContext` and
`AgentSystemBuilder` lose `input_queue_arn`, and daemon/lambda display paths now emit
`AgentEvent` instead of `DisplayEvent`.
Co-authored-by: Infinity 🤖 <infinity@hydro.run>
PR: #92
shadaj
force-pushed
the
sandbox-eb0ff46e-96e1-4d2d-8c0b-9c683fa4d1b9
branch
from
August 4, 2026 22:36
5689aff to
7a10b86
Compare
Deploying infinity with
|
| Latest commit: |
32bcb39
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://fe19753d.infinity-dc7.pages.dev |
| Branch Preview URL: | https://sandbox-eb0ff46e-96e1-4d2d-8.infinity-dc7.pages.dev |
…on + lambda onto it
Introduce `infinity_agent_core::system`, a builder-based, object-oriented API for
running agents, and rebuild both production embeddings on top of it. The docs for
`infinity-runtime` are rewritten around the new API.
Core (`infinity_agent_core::system`):
- `AgentSystemBuilder`: two construction modes — `new(stores, model, sender)` builds a
step-mode `AgentSystem` for serverless platforms; `new_local(stores, model)` builds a
`LocalAgentSystem` with an internal in-process queue (`ChannelSender`).
- `Thread`: loads one conversation thread from the stores. `step(inputs, observer,
defer, cancel_rx)` runs one slice with the deferral policy applied (filter →
prepare → completion → history sync → observer commit barrier → tool dispatch);
`step_no_defer(batch, observer, cancel_rx)` is the raw step for callers that
compose `filter_deferrable` themselves (the local driver, which must skip no-op
steps when everything was deferred). Per-thread configuration is resolved lazily on
first step so loading a thread never boots tool servers.
- `LocalAgentSystem::start` runs a full actor-system-style runtime: a router plus one
driver task per active thread, with input batching, `<interrupt>` handling for user
text during a completion, deferral of subscription events while a non-passive tool
call is pending, auto-compaction above 75% of the context window, and race-free idle
exit/respawn. `RunningSystem` exposes `sender()`, `send_user_text`, ack'd
`subscribe`, `active_threads`, a `thread_exits` channel for per-conversation resource
teardown, and `begin_shutdown` for process exit. The system itself runs for the
process lifetime.
- `ThreadHandle`: `LocalAgentSystem::start_with_handles()` runs the system with a
built-in channel-based observer (`HandleObserver`) whose subscriber registry is
shared across driver respawns; `RunningSystem::thread_handle(thread_id)` then
attaches to a thread (creating its subscription even before the thread exists) and
returns a handle with `replay()` for the initial snapshot, an unbounded `events`
queue of `AgentEvent`s (exactly-once relative to the replay), and
`send_user_text`/`send` for input.
- `ThreadObserver`: synchronous `on_event(AgentEvent)` fan-out (exactly-once relative
to `on_subscribe` replay snapshots) plus awaited durability hooks
(`on_user_choice_required`/`_dismissed`, `on_commit` before tool dispatch).
- `ModelSource` (per-round model resolution; enables mid-session model switching) with
`StaticModel`; `ThreadConfigSource` (per-thread tools/prompt/notifier; enables
per-session RAP servers) with `StaticThreadConfig`; `DeferQueue` with
`InMemoryDeferQueue`/`NoDeferral`.
- `AgentEvent`/`ReplaySnapshot`/`UserChoice` display types; `Tool::is_passive()`;
in-memory `ConversationStore`/`StateStore` implementations in
`infinity_agent_core::stores`; tokio-backed sleep tools moved into the core
(`with_tokio_sleep_tools`).
- The core API is platform-neutral: `input_queue_arn` is removed from `ToolContext`
and the builder. Platform-specific configuration lives on the tools that need it
(the Lambda sleep tools now carry the input queue ARN as a field, alongside their
scheduler client, role ARN, and delay queue URL).
- All 20 daemon agent-loop tests migrated into core `system/tests.rs` with
byte-identical snapshots, plus 3 new `ThreadHandle` tests (send/receive + late
replay, survival across idle/respawn, dropped-handle pruning).
Daemon (`infinity-daemon`):
- One daemon-lifetime agent system replaces per-session agent loops. Sessions are root
threads; a `thread_exits` watcher marks sessions idle and shuts down their RAP
servers when no keep-alive client is attached.
- New `rap_servers.rs`: `ManagedRapServer`/`ManagedRapTool`/`SessionRapManager` — RAP
servers boot lazily per session via `ThreadConfigSource` and reboot transparently
after idle shutdown. Config-source info messages ("Using local config", etc.) are
preserved at first resolve.
- `DaemonObserver` implements the observer hooks (usage persistence, pending user
choices, live-attach replay including mid-stream thinking).
- `CatalogModelSource` resolves each thread's persisted model selection per round.
- Deleted: `session/thread_worker.rs`, `session/agent_loop.rs`, `sleep_tools.rs`,
`InMemoryMessageSender`, `Session`, `spawn_session`, `AgentMessage`.
Lambda (`infinity-agent-lambda`): event handler rewritten on
`AgentSystemBuilder::new(...).build()` + `thread()` + the deferral-aware
`Thread::step` with an `EventCollector`, replacing the hand-rolled `process_batch`
plumbing.
Docs (`docs/docs/infinity-runtime`): the single "Rust API" page is replaced by two
sections. "The Agent System API" (overview, building-a-system, running-locally,
step-mode, observers) documents the new high-level API — including thread handles and
the step/step_no_defer split — and the patterns both embeddings use; "The Low-Level
API" (overview, history-manager, completion-loop) documents the platform traits and
loop pieces underneath and when to use them. Cross-references across
overview/architecture/built-in-tools/deploying-on-lambda updated.
BREAKING CHANGE: `infinity-daemon` no longer exports `sleep_tools`, `AgentMessage`,
`thread_worker`, `agent_loop`, `Session`, or `InMemoryMessageSender`; `SessionManager`'s
API is reshaped around the single agent system and `SharedSessionManager` is now
`Rc<tokio::Mutex<...>>`. In `infinity-agent-core`, builder tools are stored as
`Rc<dyn Tool<M>>`, `Tool` gains a defaulted `is_passive` method, `ToolContext` and
`AgentSystemBuilder` lose `input_queue_arn`, and daemon/lambda display paths now emit
`AgentEvent` instead of `DisplayEvent`.
Co-authored-by: Infinity 🤖 <infinity@hydro.run>
PR: #92
shadaj
force-pushed
the
sandbox-eb0ff46e-96e1-4d2d-8c0b-9c683fa4d1b9
branch
from
August 4, 2026 23:59
7a10b86 to
32bcb39
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Introduce
infinity_agent_core::system, a builder-based, object-oriented API forrunning agents, and rebuild both production embeddings on top of it. The docs for
infinity-runtimeare rewritten around the new API.Core (
infinity_agent_core::system):AgentSystemBuilder: two construction modes —new(stores, model, sender)builds astep-mode
AgentSystemfor serverless platforms;new_local(stores, model)builds aLocalAgentSystemwith an internal in-process queue (ChannelSender).Thread: loads one conversation thread from the stores;step(inputs, observer, cancel_rx)runs one slice (prepare → completion → history sync → observer commitbarrier → tool dispatch). Per-thread configuration is resolved lazily on first step so
loading a thread never boots tool servers.
LocalAgentSystem::startruns a full actor-system-style runtime: a router plus onedriver task per active thread, with input batching,
<interrupt>handling for usertext during a completion, deferral of subscription events while a non-passive tool
call is pending, auto-compaction above 75% of the context window, and race-free idle
exit/respawn.
RunningSystemexposessender(),send_user_text, ack'dsubscribe,active_threads, athread_exitschannel for per-conversation resourceteardown, and
begin_shutdownfor process exit. The system itself runs for theprocess lifetime.
ThreadHandle:LocalAgentSystem::start_with_handles()runs the system with abuilt-in channel-based observer (
HandleObserver) whose subscriber registry isshared across driver respawns;
RunningSystem::thread_handle(thread_id)thenattaches to a thread (creating its subscription even before the thread exists) and
returns a handle with
replay()for the initial snapshot, an unboundedeventsqueue of
AgentEvents (exactly-once relative to the replay), andsend_user_text/sendfor input.ThreadObserver: synchronouson_event(AgentEvent)fan-out (exactly-once relativeto
on_subscribereplay snapshots) plus awaited durability hooks(
on_user_choice_required/_dismissed,on_commitbefore tool dispatch).ModelSource(per-round model resolution; enables mid-session model switching) withStaticModel;ThreadConfigSource(per-thread tools/prompt/notifier; enablesper-session RAP servers) with
StaticThreadConfig;DeferQueuewithInMemoryDeferQueue/NoDeferral.AgentEvent/ReplaySnapshot/UserChoicedisplay types;Tool::is_passive();in-memory
ConversationStore/StateStoreimplementations ininfinity_agent_core::stores; tokio-backed sleep tools moved into the core(
with_tokio_sleep_tools).system/tests.rswithbyte-identical snapshots, plus 3 new
ThreadHandletests (send/receive + latereplay, survival across idle/respawn, dropped-handle pruning).
Daemon (
infinity-daemon):threads; a
thread_exitswatcher marks sessions idle and shuts down their RAPservers when no keep-alive client is attached.
rap_servers.rs:ManagedRapServer/ManagedRapTool/SessionRapManager— RAPservers boot lazily per session via
ThreadConfigSourceand reboot transparentlyafter idle shutdown. Config-source info messages ("Using local config", etc.) are
preserved at first resolve.
DaemonObserverimplements the observer hooks (usage persistence, pending userchoices, live-attach replay including mid-stream thinking).
CatalogModelSourceresolves each thread's persisted model selection per round.session/thread_worker.rs,session/agent_loop.rs,sleep_tools.rs,InMemoryMessageSender,Session,spawn_session,AgentMessage.Lambda (
infinity-agent-lambda): event handler rewritten onAgentSystemBuilder::new(...).build()+thread()/filter_deferrable/stepwith anEventCollector, replacing the hand-rolledprocess_batchplumbing.Docs (
docs/docs/infinity-runtime): the single "Rust API" page is replaced by twosections. "The Agent System API" (overview, building-a-system, running-locally,
step-mode, observers) documents the new high-level API — including thread handles —
and the patterns both embeddings use; "The Low-Level API" (overview, history-manager,
completion-loop) documents the platform traits and loop pieces underneath and when to
use them. Cross-references across overview/architecture/built-in-tools/
deploying-on-lambda updated.
BREAKING CHANGE:
infinity-daemonno longer exportssleep_tools,AgentMessage,thread_worker,agent_loop,Session, orInMemoryMessageSender;SessionManager'sAPI is reshaped around the single agent system and
SharedSessionManageris nowRc<tokio::Mutex<...>>. Ininfinity-agent-core, builder tools are stored asRc<dyn Tool<M>>,Toolgains a defaultedis_passivemethod, and daemon/lambdadisplay paths now emit
AgentEventinstead ofDisplayEvent.