Skip to main content

agent_block_core/bridge/
mod.rs

1//! Lua Stdlib Bridge — injects all `*.*` global APIs into the Lua VM.
2//!
3//! Each submodule registers one namespace:
4//!
5//! | Module | Lua namespace | Purpose |
6//! |--------|--------------|---------|
7//! | `mesh` | `mesh.*`     | Agent-to-agent mesh communication |
8//! | `mcp`  | `mcp.*`      | MCP server management |
9//! | `sh`   | `sh.*`       | Shell command execution |
10//! | `tool` | `tool.*`     | Tool registry (define and call tools from Lua) |
11//! | `http` | `http.*`     | Async HTTP client |
12//! | `log`  | `log.*`, `env.*` | Logging and environment access |
13//! | `ts`   | `std.ts.*`   | SQLite-backed time-series primitive (in-tree) |
14
15pub mod bus;
16pub mod config;
17pub mod http;
18pub mod kv;
19pub mod llm;
20pub mod log;
21pub mod mcp;
22pub mod mesh;
23pub mod sh;
24pub mod sql;
25pub mod task;
26pub mod tool;
27pub mod ts;
28
29use mlua::prelude::*;
30
31use crate::host::HostContext;
32
33// Re-export `obs` from agent-block-types so that existing
34// `crate::bridge::obs::*` paths inside core keep compiling without
35// duplicating the module body.
36pub use agent_block_types::obs;
37
38// Re-export the Lua ↔ JSON converters from agent-block-mcp.  They live in
39// the MCP crate because the rmcp handler depends on them; core only needs
40// to forward `lua_to_json` / `json_to_lua` for the in-process bridges
41// (llm / mesh / mcp.lua) that historically reached `crate::bridge::*`.
42pub use agent_block_mcp::lua_json::{json_to_lua, lua_to_json};
43
44/// Register bridge APIs shared between main VM and handler VM.
45///
46/// Registers everything except `bus::*`.  Split out from `register_all` so
47/// the handler-side Isle can re-use the same set of bridges without
48/// installing the main-VM-only `bus` global.
49///
50/// `is_handler_side` is forwarded to `mesh::register` so the handler Isle
51/// can skip the `mesh.on` alias (which depends on `bus.on` and would fail
52/// because the handler Isle does not expose a `bus` global).
53fn register_non_bus_bridges(lua: &Lua, ctx: &HostContext, is_handler_side: bool) -> LuaResult<()> {
54    mesh::register(lua, ctx, is_handler_side)?;
55    sh::register(lua, ctx)?;
56    tool::register(lua)?;
57    log::register(lua, ctx)?;
58    mcp::register(lua, ctx)?;
59    http::register(lua, ctx)?;
60    llm::register(lua)?;
61    kv::register(lua, ctx)?;
62    sql::register(lua, ctx)?;
63    ts::register(lua, ctx)?;
64    task::register(lua)?;
65    Ok(())
66}
67
68/// Register all bridge APIs into the Lua state (main Isle).
69///
70/// Note: `fs`, `env`, `json`, `path`, `time` are provided by mlua-batteries
71/// (registered as `std.*` in host.rs). This function registers only
72/// agent-block-specific APIs.
73pub fn register_all(lua: &Lua, ctx: &HostContext) -> LuaResult<()> {
74    // bus must register before mesh — the mesh.on alias (see
75    // bridge/mesh.rs) reads the `bus` global produced here.
76    bus::register(lua, ctx)?;
77    register_non_bus_bridges(lua, ctx, false)
78}
79
80/// Register bridge APIs for the handler Isle.
81///
82/// The handler Isle runs Lua handlers forwarded from the main Isle's
83/// `bus.on` / `bus.on_any` via bytecode transfer. It therefore needs the
84/// dispatcher-side globals (`__bus_handlers`, `__bus_on_any`,
85/// `__bus_dispatch`) installed by
86/// [`bus::install_bus_dispatcher_on_handler_isle`], but does **not** expose
87/// the `bus.*` Lua table — nested `bus.on(...)` from inside a handler is
88/// intentionally unsupported.
89pub fn register_all_handler_side(lua: &Lua, ctx: &HostContext) -> LuaResult<()> {
90    bus::install_bus_dispatcher_on_handler_isle(lua)?;
91    agent_block_mcp::handler::install_mcp_dispatcher_on_handler_isle(lua)?;
92    register_non_bus_bridges(lua, ctx, true)
93}