#[non_exhaustive]pub struct InboundMessageMeta {
pub kind: InboundKind,
pub sender_id: Option<String>,
pub msg_id: Option<String>,
pub inbound_ts: Option<DateTime<Utc>>,
pub reply_to_msg_id: Option<String>,
pub has_media: bool,
pub origin_session_id: Option<Uuid>,
}Expand description
Binding context propagated to tool calls so extensions and MCP servers can route per-(channel, account_id, agent_id) tuple without re-deriving it from each tool call’s payload.
Serialised under _meta.nexo.binding in JSON-RPC tools/call
(extensions ignore unknown fields) and as the meta block of
MCP call_tool_with_meta.
agent_id is mandatory; the rest are Option because some
dispatch paths (delegation receive, heartbeat bootstrap, tests)
have no binding match — None is the correct state, not a
sentinel string.
mcp_channel_source is populated when the inbound that
triggered this turn arrived via an MCP channel server (e.g.,
"slack", "telegram"). Lets a tool distinguish
“telegram-binding answered via MCP slack server” from
“telegram-binding answered via native Telegram plugin” while
still seeing the same (channel, account_id) binding tuple.
Matches the goal_turns.source = "channel:slack" audit column.
Per-turn metadata about the inbound message that triggered the
agent turn.
Stamped on every tool call dispatched to a stdio
extension or an MCP server (under
params._meta.nexo.inbound). All fields except kind are
optional; consumers must tolerate absence and branch
gracefully.
§Example — external user message
use nexo_tool_meta::{InboundKind, InboundMessageMeta};
let meta = InboundMessageMeta::external_user("+5491100", "wa.ABCD1234");
assert_eq!(meta.kind, InboundKind::ExternalUser);
assert_eq!(meta.sender_id.as_deref(), Some("+5491100"));
assert_eq!(meta.msg_id.as_deref(), Some("wa.ABCD1234"));§Example — internal system tick
use nexo_tool_meta::{InboundKind, InboundMessageMeta};
let meta = InboundMessageMeta::internal_system();
assert_eq!(meta.kind, InboundKind::InternalSystem);
assert!(meta.sender_id.is_none());
assert!(meta.msg_id.is_none());Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.kind: InboundKindOrigin discriminator. Always present when the bucket is.
sender_id: Option<String>Provider-native sender id (E.164 phone, telegram_user_id,
RFC822 from-address, slack U-id, …). None for kinds
other than ExternalUser and for paths where the provider
does not expose a sender id (e.g. webhook with no auth).
msg_id: Option<String>Provider-native message id (single canonical, no shortened
alias). Used for idempotency, dedupe, and as the
reply_to_msg_id target on subsequent turns. When a
debounce window collapses several inbound messages into a
single turn, this carries the id of the first message
in the batch.
inbound_ts: Option<DateTime<Utc>>Inbound timestamp in UTC. Wire shape: RFC3339 string via
chrono’s serde adapter. Producers must clamp wildly-skewed
provider timestamps to now() before emitting.
reply_to_msg_id: Option<String>Provider-native id of the message this one replies to.
None when the inbound is not a reply.
has_media: booltrue when the inbound carries non-text media
(image/audio/video/file/sticker). Microapps gate
media-aware tools on this; the actual bytes/URLs live in
arguments, not in _meta.
origin_session_id: Option<Uuid>Origin session id when kind == InterSession (delegation
receive). None otherwise.
Implementations§
Source§impl InboundMessageMeta
impl InboundMessageMeta
Sourcepub fn external_user(
sender_id: impl Into<String>,
msg_id: impl Into<String>,
) -> InboundMessageMeta
pub fn external_user( sender_id: impl Into<String>, msg_id: impl Into<String>, ) -> InboundMessageMeta
Build the minimum meta for an external user message (channel plugin / webhook / MCP-channel inbound).
Sourcepub fn internal_system() -> InboundMessageMeta
pub fn internal_system() -> InboundMessageMeta
Build the meta for a heartbeat / scheduler tick or a
yaml-declared internal_system event-subscriber binding.
Sourcepub fn inter_session(origin_session_id: Uuid) -> InboundMessageMeta
pub fn inter_session(origin_session_id: Uuid) -> InboundMessageMeta
Build the meta for an inter-agent delegation receive.
origin_session_id is required — None would be
indistinguishable from internal_system.
Sourcepub fn with_ts(self, ts: DateTime<Utc>) -> InboundMessageMeta
pub fn with_ts(self, ts: DateTime<Utc>) -> InboundMessageMeta
Builder: layer the inbound timestamp.
Sourcepub fn with_reply_to(
self,
reply_to_msg_id: impl Into<String>,
) -> InboundMessageMeta
pub fn with_reply_to( self, reply_to_msg_id: impl Into<String>, ) -> InboundMessageMeta
Builder: layer the reply-to message id.
Sourcepub fn with_media(self) -> InboundMessageMeta
pub fn with_media(self) -> InboundMessageMeta
Builder: flag that the inbound carries non-text media.
Trait Implementations§
Source§impl Clone for InboundMessageMeta
impl Clone for InboundMessageMeta
Source§fn clone(&self) -> InboundMessageMeta
fn clone(&self) -> InboundMessageMeta
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for InboundMessageMeta
impl Debug for InboundMessageMeta
Source§impl<'de> Deserialize<'de> for InboundMessageMeta
impl<'de> Deserialize<'de> for InboundMessageMeta
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<InboundMessageMeta, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<InboundMessageMeta, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
impl Eq for InboundMessageMeta
Source§impl PartialEq for InboundMessageMeta
impl PartialEq for InboundMessageMeta
Source§impl Serialize for InboundMessageMeta
impl Serialize for InboundMessageMeta
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
impl StructuralPartialEq for InboundMessageMeta
Auto Trait Implementations§
impl Freeze for InboundMessageMeta
impl RefUnwindSafe for InboundMessageMeta
impl Send for InboundMessageMeta
impl Sync for InboundMessageMeta
impl Unpin for InboundMessageMeta
impl UnsafeUnpin for InboundMessageMeta
impl UnwindSafe for InboundMessageMeta
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more