use super::super::waiting::{
AgentDelivery, WaitingLimits,
tests::{DiskFixture, create_agent, held, keeper, placer, pull_limits, store},
};
use super::super::{DraftExecutor, tests::Issuer};
use super::*;
use liminal::channel::{ChannelConfig, ChannelHandle, ChannelMode, Schema};
use lys_pass::drafts::execute_once;
use serde_json::json;
use std::collections::BTreeMap;
use std::num::NonZeroUsize;
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn held_agent_act_clears_waiting_and_publishes_one_real_durable_inbox_outcome()
-> Result<(), Box<dyn std::error::Error>> {
let issuer = Issuer::new(vec![(200, json!({})); 8])?;
let disk = DiskFixture::new()?;
let placement = placer(&issuer)?;
let owners = disk.owners(placement.clone())?;
let lifecycle = disk.lifecycle(placement)?;
let created = create_agent("builder-create")?;
held(
&keeper(
owners.clone(),
lifecycle.clone(),
"fixture-owner",
"person",
&created,
)?,
&created,
)?;
let mut first = DraftExecutor {
store: store(&owners)?,
limits: pull_limits()?,
at_ms: 2000,
};
execute_once(&created, &mut first)?;
let draft = super::super::admin::tests::fixture_child_request(owners.clone(), lifecycle)?;
let state = owners
.agents()
.retained()
.value("agents.builder.state")?
.ok_or("waiting state missing")?;
assert_eq!(state["state"], "waiting");
assert_eq!(state["words"], draft.words);
assert_eq!(state["draft"], draft.id);
assert_eq!(state["since"], 1000);
let inbox = ChannelHandle::new_durable(
ChannelConfig::new(
"agents.builder.inbox".into(),
Schema::new(json!({}))?,
ChannelMode::Durable,
),
disk.store,
)?;
let waiting = WaitingLimits {
drafts: NonZeroUsize::new(8).ok_or("zero bound")?,
words_bytes: NonZeroUsize::new(4096).ok_or("zero bound")?,
identifier_bytes: NonZeroUsize::new(256).ok_or("zero bound")?,
};
let delivery = AgentDelivery::new(
&owners,
BTreeMap::from([("builder".into(), inbox.clone())]),
"fixture-exchange".into(),
waiting,
)?;
let mut executor = DraftExecutor {
store: AgentDraftStore::new(&owners, delivery),
limits: pull_limits()?,
at_ms: 3000,
};
let receipt = execute_once(&draft, &mut executor)?;
executor.store.deliver_outcome(&draft, &receipt)?;
executor.store.deliver_outcome(&draft, &receipt)?;
assert_eq!(inbox.durable_positions()?[0], 1);
let state = owners
.agents()
.retained()
.value("agents.builder.state")?
.ok_or("terminal state missing")?;
assert_eq!(state["state"], "gone");
assert_eq!(state["outcome"], "executed");
assert_eq!(
owners
.agents()
.registry()
.record("child")?
.transitions
.len(),
1
);
let message = owners
.journal()
.read(|snapshot| serde_json::to_value(&snapshot.deliveries[&draft.id]))??;
assert_eq!(message["message"]["draft"], draft.id);
assert_eq!(message["message"]["meta"]["from"], "fixture-exchange");
issuer.finish()
}