1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
//! mesh.* — Agent mesh communication bridge (async).
//!
//! `mesh.send` and `mesh.request` use `create_async_function` so that
//! Lua coroutines yield while waiting for mesh I/O.
use mlua::prelude::*;
use std::sync::Arc;
use std::time::Duration;
use crate::host::HostContext;
pub fn register(lua: &Lua, ctx: &HostContext) -> LuaResult<()> {
let mesh_tbl = lua.create_table()?;
match &ctx.mesh_agent {
None => {
// All functions return error when mesh is not connected
for name in &["send", "request", "on", "agent_id"] {
let n = name.to_string();
mesh_tbl.set(
*name,
lua.create_function(move |_, _: LuaValue| {
Err::<LuaValue, _>(LuaError::external(format!(
"mesh.{n}: mesh not connected (no --relay specified)"
)))
})?,
)?;
}
}
Some(agent) => {
let agent_send = Arc::clone(agent);
mesh_tbl.set(
"send",
lua.create_async_function(
move |lua, (agent_id_str, payload): (String, LuaValue)| {
let agent = Arc::clone(&agent_send);
async move {
use crate::bridge::lua_to_json;
let payload_json = lua_to_json(&lua, payload)?;
let target = agent_mesh_core::identity::AgentId::from_raw(agent_id_str);
agent
.request(&target, payload_json, Duration::from_secs(10))
.await
.map_err(LuaError::external)?;
Ok(())
}
},
)?,
)?;
let agent_req = Arc::clone(agent);
mesh_tbl.set(
"request",
lua.create_async_function(
move |lua, (agent_id_str, payload): (String, LuaValue)| {
let agent = Arc::clone(&agent_req);
async move {
use crate::bridge::{json_to_lua, lua_to_json};
let payload_json = lua_to_json(&lua, payload)?;
let target = agent_mesh_core::identity::AgentId::from_raw(agent_id_str);
let resp = agent
.request(&target, payload_json, Duration::from_secs(30))
.await
.map_err(LuaError::external)?;
json_to_lua(&lua, resp)
}
},
)?,
)?;
let agent_id_str = agent.agent_id().to_string();
mesh_tbl.set(
"agent_id",
lua.create_function(move |_, ()| Ok(agent_id_str.clone()))?,
)?;
// TODO: mesh.on — register incoming request handler (Phase 2)
// Requires wiring Lua function into RequestHandler trait via Arc<Mutex<LuaFunction>>.
mesh_tbl.set(
"on",
lua.create_function(|_, _: LuaFunction| {
Err::<(), _>(LuaError::external("mesh.on not yet implemented (Phase 2)"))
})?,
)?;
}
}
lua.globals().set("mesh", mesh_tbl)?;
Ok(())
}