tests: restore the self_run ceiling and flush tests and the persona DM-room, flag and outcome tests on the usage-only surface; close the red tests; regenerate public_surface.txt; strip stale initiative and dial wording
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
090712edfb
commit
a6302f0dd9
8 changed files with 361 additions and 84 deletions
|
|
@ -971,9 +971,10 @@ fn schema_prints_the_published_files() {
|
|||
let names = run(&[], &["schema"], None);
|
||||
assert_eq!(names.code, 0);
|
||||
let names: Vec<&str> = names.out.lines().collect();
|
||||
assert_eq!(names.len(), 15, "{names:?}");
|
||||
assert_eq!(names.len(), 16, "{names:?}");
|
||||
assert_eq!(names[0], "campaign");
|
||||
assert_eq!(names[14], "selection");
|
||||
assert_eq!(names[14], "pulse");
|
||||
assert_eq!(names[15], "selection");
|
||||
for kind in PipelineKind::ALL {
|
||||
assert!(names.contains(&kind.name()), "{}", kind.name());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ wrong or the mind cannot be reached.
|
|||
|
||||
## The heartbeat
|
||||
|
||||
`mind-heartbeat` is the one process that decides who wakes and when: acting burns initiative by spend, the classifier's urgency multiplies how fast it regains, and the operator tagging or naming a Persona fills it. `mind-heartbeat timeline` prints its latest record.
|
||||
`mind-heartbeat` is the one process that decides who wakes and when: each beat falls when the Minds' voted tempo has passed and goes to the Mind that has waited longest, bent by the urgency she declares and a member addressing her; the operator tagging or naming a Persona launches her at once. `mind-heartbeat timeline` prints its latest record.
|
||||
|
||||
The actuator has its own ignored test, `the_real_bin_finds_her_run_...` in
|
||||
`tests/self_run.rs`: the real `mind-self-run` against the real daemon with a
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
//! and (a later cut) topics she subscribed to. Two things launch a Persona off
|
||||
//! the beat: the operator tagging or naming her, once per message, and her own
|
||||
//! Self run having ended since her last turn. Nothing is metered here: no
|
||||
//! dollars, no budget, no model call.
|
||||
//! meter and no model call.
|
||||
//!
|
||||
//! The heartbeat owns `heartbeat.cc` and is its only writer; Persona units read
|
||||
//! it. The brakes stay the operator's and are read on every poll. Busy and idle
|
||||
|
|
@ -49,7 +49,7 @@ const PENDING_PAGES: usize = 16;
|
|||
/// Who a Persona is, for the two things the heartbeat matches on: the Matrix
|
||||
/// user id its tags carry, and the names a message may call it by. Each Mind is
|
||||
/// its own Huginn daemon, so the entry also carries the daemon the Persona's
|
||||
/// control, initiative and launches are read from.
|
||||
/// control, runs and launches are read from.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct PersonaId {
|
||||
pub slug: Slug,
|
||||
|
|
@ -203,7 +203,7 @@ pub trait TempoView {
|
|||
|
||||
/// The store as a CultCache single-file store under the unit's state directory.
|
||||
/// It registers the state and the trace and nothing else: a file still holding
|
||||
/// the dollar initiative documents does not decode, and every use of it fails
|
||||
/// any older document does not decode, and every use of it fails
|
||||
/// naming the file. It is never migrated.
|
||||
pub struct FileStore {
|
||||
path: PathBuf,
|
||||
|
|
|
|||
|
|
@ -366,7 +366,8 @@ fn the_operator_naming_a_persona_launches_her_at_once_off_the_beat_and_once_per_
|
|||
// Her turn fails without acking; the same message does not launch her again.
|
||||
rig.end_run(BOB);
|
||||
assert_eq!(rig.poll(), Outcome::Polled { launched: vec![] });
|
||||
assert_eq!(rig.runs(BOB), 3);
|
||||
assert_eq!(rig.runs(BOB), 2, "her old turn and the one launch, no second launch for the same message");
|
||||
assert_eq!(rig.launched(), vec![Slug("bob".into())]);
|
||||
// A tag in m.mentions counts as naming.
|
||||
rig.say(ANN, delivery(2, "@op:chat", "please look", &["@ann:chat"]));
|
||||
assert_eq!(rig.poll(), Outcome::Polled { launched: vec![Slug("ann".into())] });
|
||||
|
|
|
|||
|
|
@ -945,3 +945,163 @@ fn a_usage_readout_that_cannot_be_had_is_said_and_the_turn_goes_on() {
|
|||
assert_eq!((failure, answered), (None, 1), "usage is display only");
|
||||
assert!(rig.connector.requests.borrow()[0].input.contains("Plan usage: unavailable."));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_turn_is_one_tool_less_call_constrained_to_the_reply_schema_with_her_rooms() {
|
||||
let rig = Rig::new(vec![operator_says(1, "a")], &[says(&[])]);
|
||||
rig.go();
|
||||
let requests = rig.connector.requests.borrow();
|
||||
assert_eq!(requests[0].caller, INSTANCE);
|
||||
assert!(requests[0].instructions.contains("You are Eureka."));
|
||||
let schema: serde_json::Value = serde_json::from_str(&requests[0].output_schema_json).unwrap();
|
||||
assert_eq!(schema["properties"]["say"]["items"]["properties"]["room"]["enum"], json!(["swarm", "usage", "operator"]));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_members_dm_is_answered_in_its_room_and_no_other_unconfigured_room_is() {
|
||||
let dm = "!abc:chat";
|
||||
let rig = Rig::new(vec![direct(1, dm, "@m:chat", "hello, are you there")], &[says(&[(dm, "yes")])]);
|
||||
let Outcome::Served { failure, answered, .. } = rig.go() else { panic!("served") };
|
||||
assert_eq!((failure, answered), (None, 1));
|
||||
assert_eq!(rig.chat.sent.borrow()[0].room_alias, dm);
|
||||
let request = &rig.connector.requests.borrow()[0];
|
||||
let schema: serde_json::Value = serde_json::from_str(&request.output_schema_json).unwrap();
|
||||
assert_eq!(schema["properties"]["say"]["items"]["properties"]["room"]["enum"], json!(["swarm", "usage", "operator", dm]));
|
||||
assert!(request.input.contains(dm), "the DM's room is among the rooms she is told she may speak in");
|
||||
|
||||
let rig = Rig::new(vec![direct(1, dm, "@m:chat", "hello")], &[says(&[("!other:chat", "psst")])]);
|
||||
let Outcome::Served { failure, .. } = rig.go() else { panic!("served") };
|
||||
assert_eq!(failure, Some(Failure::RoomNotAllowed));
|
||||
assert!(rig.chat.sent.borrow().is_empty() && rig.chat.acked.borrow().is_empty());
|
||||
|
||||
let rig = Rig::new(vec![delivery(1, "!notdm:chat", "@m:chat", "hello")], &[says(&[("!notdm:chat", "psst")])]);
|
||||
let Outcome::Served { failure, .. } = rig.go() else { panic!("served") };
|
||||
assert_eq!(failure, Some(Failure::RoomNotAllowed), "a room that is not a DM is hers only when configured");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deliveries_from_different_dm_rooms_are_never_in_one_turn() {
|
||||
let (a, b) = ("!a:chat", "!b:chat");
|
||||
let pending = vec![
|
||||
direct(1, a, "@ann:chat", "secret-a"),
|
||||
direct(2, b, "@bob:chat", "hi-b"),
|
||||
delivery(3, "swarm", "@m:chat", "public-c"),
|
||||
direct(4, a, "@ann:chat", "more-a"),
|
||||
direct(5, a, "@ann:chat", "again-a"),
|
||||
];
|
||||
let replies = [says(&[(a, "1")]), says(&[(b, "2")]), says(&[("swarm", "3")]), says(&[(a, "4")])];
|
||||
let rig = Rig::new(pending, &replies);
|
||||
let Outcome::Served { failure, answered, .. } = rig.go() else { panic!("served") };
|
||||
assert_eq!((failure, answered), (None, 4));
|
||||
let inputs: Vec<String> = rig.connector.requests.borrow().iter().map(|request| request.input.clone()).collect();
|
||||
let texts = ["secret-a", "hi-b", "public-c", "more-a"];
|
||||
for (turn, input) in inputs.iter().enumerate() {
|
||||
for (other, text) in texts.iter().enumerate() {
|
||||
assert_eq!(input.contains(text), turn == other, "turn {turn} text {text}");
|
||||
}
|
||||
}
|
||||
assert!(inputs[3].contains("again-a"), "one room's consecutive deliveries share its turn");
|
||||
assert!(!inputs[0].contains("again-a"), "a later delivery waits for its turn");
|
||||
assert_eq!(*rig.chat.acked.borrow(), vec![1, 2, 3, 5]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn outcomes_and_failures_read_as_one_line_each_without_values() {
|
||||
assert_eq!(Outcome::Dead(HeldReason::BrakeHeld).to_string(), "dead: BrakeHeld");
|
||||
let served = Outcome::Served { run: run_ref("r1"), answered: 2, failure: Some(Failure::Send), self_run: Some(run_ref("s1")) };
|
||||
let line = served.to_string();
|
||||
assert!(line.contains("r1") && line.contains("answered 2") && line.contains("a send was refused or failed") && line.contains("self run") && line.contains("s1"), "{line}");
|
||||
assert_eq!(Failure::Held(HeldReason::BrakeAbsent).to_string(), "held: BrakeAbsent");
|
||||
let all = [
|
||||
Failure::Chat,
|
||||
Failure::Persona,
|
||||
Failure::Doctrine,
|
||||
Failure::DoctrineTooLarge,
|
||||
Failure::Connector,
|
||||
Failure::Undecodable,
|
||||
Failure::RoomNotAllowed,
|
||||
Failure::Send,
|
||||
Failure::SelfRun,
|
||||
Failure::Pulse,
|
||||
Failure::Ack,
|
||||
];
|
||||
for failure in all {
|
||||
assert!(!failure.to_string().is_empty());
|
||||
}
|
||||
let texts: std::collections::BTreeSet<_> = all.map(|failure| failure.to_string()).into();
|
||||
assert_eq!(texts.len(), all.len(), "each failure reads differently");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_turn_is_named_by_its_run_and_its_number() {
|
||||
let rig = Rig::new(vec![operator_says(1, "a")], &(0..4).map(|_| says(&[("swarm", "x")])).collect::<Vec<_>>());
|
||||
rig.mind.committed(vec![run("woken", RunTurn::PersonaTurn, RunOperator::Mind, &[])]);
|
||||
rig.clock.0.set(600_000);
|
||||
let (deliveries, next) = (rig.chat.deliveries.clone(), Cell::new(1));
|
||||
*rig.connector.during.borrow_mut() = Some(Box::new(move || {
|
||||
next.set(next.get() + 1);
|
||||
if next.get() < 3 {
|
||||
deliveries.borrow_mut().push(operator_says(next.get(), "more"));
|
||||
}
|
||||
}));
|
||||
let Outcome::Served { run: carried, answered, .. } = rig.start_with(&config()) else { panic!("served") };
|
||||
assert_eq!((carried, answered), (run_ref("woken"), 2));
|
||||
let ids: Vec<_> = rig.connector.requests.borrow().iter().map(|request| request.request_id.clone()).collect();
|
||||
assert_eq!(ids, ["woken-t0", "woken-t1"]);
|
||||
let trace = rig.trace.0.borrow();
|
||||
assert_eq!(trace.iter().map(|record| (record.run.as_str(), record.turn)).collect::<Vec<_>>(), [("woken", 0), ("woken", 1)]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_persona_flags_are_taken_out_and_the_rest_is_left_for_the_shared_parser() {
|
||||
let args = |text: &str| text.split_whitespace().map(String::from).collect::<Vec<_>>();
|
||||
let (parsed, rest) = Config::from_args(
|
||||
&args("--instance eureka --rooms swarm,usage,operator --operator @op:chat,@op2:chat --self-sender @eureka:chat --endpoint rudp://10.0.0.1:1"),
|
||||
"usage",
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(parsed.rooms, ["swarm", "usage", "operator"]);
|
||||
assert_eq!((parsed.own_sender.as_str(), parsed.max_turns), ("@eureka:chat", MAX_TURNS_PER_START));
|
||||
assert_eq!(parsed.operators, ["@op:chat", "@op2:chat"]);
|
||||
assert_eq!(rest, args("--instance eureka --endpoint rudp://10.0.0.1:1"));
|
||||
let (two, _) = Config::from_args(&args("--rooms a --operator o --self-sender s --max-turns 2"), "usage").unwrap();
|
||||
assert_eq!(two.max_turns, 2);
|
||||
for bad in [
|
||||
"--rooms a --operator o",
|
||||
"--rooms a,,b --operator o --self-sender s",
|
||||
"--rooms a --rooms a --operator o --self-sender s",
|
||||
"--rooms a --operator o --self-sender s --max-turns 0",
|
||||
"--rooms a --operator o --self-sender s --max-turns x",
|
||||
"--rooms a --operator o --self-sender",
|
||||
] {
|
||||
assert!(Config::from_args(&args(bad), "usage").is_err(), "{bad}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_persona_flags_come_from_the_environment_when_the_command_line_lacks_them() {
|
||||
let env = |name: &str| {
|
||||
Some(
|
||||
match name {
|
||||
ENV_ROOMS => "swarm,usage",
|
||||
ENV_OPERATOR => "@op:chat,@op2:chat",
|
||||
ENV_SELF_SENDER => "@eureka:chat",
|
||||
_ => "",
|
||||
}
|
||||
.to_string(),
|
||||
)
|
||||
};
|
||||
let args = |text: &str| text.split_whitespace().map(String::from).collect::<Vec<_>>();
|
||||
let (config, rest) = Config::from_args_and_env(&args("--instance eureka"), env, "usage").unwrap();
|
||||
assert_eq!(
|
||||
config,
|
||||
Config { rooms: vec!["swarm".into(), "usage".into()], operators: vec!["@op:chat".into(), "@op2:chat".into()], own_sender: "@eureka:chat".into(), max_turns: MAX_TURNS_PER_START, doctrine: vec![] }
|
||||
);
|
||||
assert_eq!(rest, ["--instance", "eureka"]);
|
||||
// A flag wins over its variable, one at a time.
|
||||
let (flagged, _) = Config::from_args_and_env(&args("--instance eureka --rooms swarm"), env, "usage").unwrap();
|
||||
assert_eq!((flagged.rooms.len(), flagged.operators.len()), (1, 2));
|
||||
// An empty variable is unset, and a missing setting is the usage error.
|
||||
assert!(Config::from_args_and_env(&args("--instance eureka"), |name| if name == ENV_ROOMS { Some(String::new()) } else { env(name) }, "usage").is_err());
|
||||
assert!(Config::from_args_and_env(&args("--instance eureka"), |_| None, "usage").is_err());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -470,6 +470,41 @@ fn a_mind_that_cannot_be_read_or_a_child_that_cannot_start_is_an_error_not_an_ou
|
|||
|
||||
// ---- what is started ------------------------------------------------------
|
||||
|
||||
#[test]
|
||||
fn claude_args_is_exactly_the_fixed_list_for_a_session() {
|
||||
let session = Uuid::parse_str(SESSION_OF_RUN_A).unwrap();
|
||||
let args = claude_args(session);
|
||||
assert_eq!(
|
||||
args,
|
||||
[
|
||||
"-p",
|
||||
"--input-format",
|
||||
"stream-json",
|
||||
"--output-format",
|
||||
"stream-json",
|
||||
"--verbose",
|
||||
"--session-id",
|
||||
SESSION_OF_RUN_A,
|
||||
"--max-turns",
|
||||
"500",
|
||||
"--permission-mode",
|
||||
"bypassPermissions",
|
||||
"--permission-prompts",
|
||||
"none",
|
||||
"--setting-sources",
|
||||
"user",
|
||||
]
|
||||
);
|
||||
// Those belong to the run measure or to the unit's managed settings.
|
||||
for forbidden in ["--resume", "--continue", "--fork-session", "--model", "--dangerously-skip-permissions", "--settings", "--system-prompt", "--max-budget"] {
|
||||
assert!(!args.iter().any(|arg| arg.starts_with(forbidden) || arg.contains("dangerously")), "{forbidden}");
|
||||
}
|
||||
// Print mode starts in Manual without a mode, and prompts none then denies.
|
||||
let mode = args.iter().position(|arg| arg == "--permission-mode").expect("mode flag");
|
||||
assert_eq!(args[mode + 1], "bypassPermissions");
|
||||
assert_eq!(MAX_TURNS, 500);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_session_id_is_uuid_v5_of_the_run_id_and_differs_per_run() {
|
||||
assert_eq!(session_id(&foreign_run("eureka:run:mind-20261022T120000000Z")).to_string(), SESSION_OF_MIND_RUN);
|
||||
|
|
@ -477,6 +512,18 @@ fn the_session_id_is_uuid_v5_of_the_run_id_and_differs_per_run() {
|
|||
assert_eq!(session_id(&run_ref("selfrun-b")).to_string(), SESSION_OF_RUN_B);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_child_is_started_for_her_run_with_the_fixed_list_whatever_the_run_record_says() {
|
||||
// The run's budget field is a dead record; nothing in what is started depends on it.
|
||||
for budget in ["0", "0.5", "10", "100"] {
|
||||
let mind = TestMind::seeded();
|
||||
mind.committed(vec![self_run("selfrun-b", budget)]);
|
||||
let ran = carry_with(&Seen::of(&mind), vec![Out(result_line())], Some(0), false);
|
||||
assert_eq!(ran.spawns.len(), 1, "{budget}");
|
||||
assert_eq!(ran.spawns[0], claude_args(Uuid::parse_str(SESSION_OF_RUN_B).unwrap()), "{budget}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_start_message_is_the_first_thing_written_and_names_the_skill_the_instance_and_the_run() {
|
||||
let ran = go(vec![Out(result_line())]);
|
||||
|
|
@ -647,6 +694,27 @@ fn read_usage_classifies_the_owners_real_records() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn records_that_share_a_message_id_count_once_and_subagent_records_never_move_the_prefix() {
|
||||
let mut steps: Vec<Step> = RECORDS.lines().map(|line| Out(line.to_string())).collect();
|
||||
steps.insert(3, Out(subagent("msg_sub", 999_999)));
|
||||
let ran = go(steps);
|
||||
assert_eq!(
|
||||
ran.out,
|
||||
"request 1 prefix 84210
|
||||
request 2 prefix 100751
|
||||
request 3 prefix 117174
|
||||
request 4 prefix 118336
|
||||
request 5 prefix 126746
|
||||
request 6 prefix 127250
|
||||
request 7 prefix 129853
|
||||
"
|
||||
);
|
||||
let (cause, _, requests, prefix) = ran.ended();
|
||||
assert_eq!((cause, requests, prefix), (Cause::Own, 7, 129_853), "the newest prefix, 129853, not a subagent's 999999");
|
||||
assert_eq!(flushes(&ran), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_prefix_is_the_newest_requests_not_the_largest() {
|
||||
let ran = go(vec![Out(at("m1", 200_000)), Out(at("m2", 150_000))]);
|
||||
|
|
@ -744,6 +812,41 @@ fn the_headroom_counts_the_requests_after_the_first_result_that_follows_the_flus
|
|||
assert_eq!(same_turn.count(&Event::Stopped(Stop::Interrupt)), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_jump_past_the_ceiling_plus_the_headroom_writes_the_flush_and_the_running_turn_cannot_use_up_the_flushs_turn() {
|
||||
let jump = carry_with(
|
||||
&Seen::of(&with_run()),
|
||||
vec![Out(at("m1", 290_000)), Out(at("m2", 400_000)), Out(at("m3", 470_000)), Out(result_line()), Out(at("m4", 459_999)), Out(at("m5", 460_000)), Out(at("m6", 470_000))],
|
||||
Some(130),
|
||||
true,
|
||||
);
|
||||
let kinds: Vec<&str> = jump
|
||||
.events
|
||||
.iter()
|
||||
.filter_map(|event| match event {
|
||||
Event::Wrote(line) if line.contains("context ceiling") => Some("flush"),
|
||||
Event::Stopped(_) => Some("interrupt"),
|
||||
Event::InputClosed => Some("closed"),
|
||||
Event::Asked(_) => Some("read"),
|
||||
_ => None,
|
||||
})
|
||||
.collect();
|
||||
// Reads: m1, m2 (the jump, which writes the flush), m3 (the running turn's 470k, past the headroom: no interrupt).
|
||||
assert_eq!(kinds[..5], ["read", "read", "flush", "read", "read"], "{kinds:?}");
|
||||
// The headroom is measured from the prefix the flush was asked at (400k) and counts the requests after the
|
||||
// first result only: 459_999 does not interrupt; 460_000 does, once, and m6 is never read.
|
||||
assert_eq!(jump.count(&Event::Stopped(Stop::Interrupt)), 1, "{kinds:?}");
|
||||
assert_eq!(jump.out, "request 1 prefix 290000
|
||||
request 2 prefix 400000
|
||||
request 3 prefix 470000
|
||||
result subtype=success is_error=true: Failed to authenticate: OAuth session expired and could not be refreshed
|
||||
request 4 prefix 459999
|
||||
request 5 prefix 460000
|
||||
");
|
||||
assert_eq!(jump.ended().0, Cause::Signalled(Stop::Interrupt));
|
||||
assert_eq!(flushes(&jump), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_child_that_ends_before_the_grace_is_never_interrupted() {
|
||||
let ran = go(vec![Out(at("m1", CEILING_TOKENS)), Out(result_line())]);
|
||||
|
|
@ -938,6 +1041,27 @@ fn the_outcome_names_how_it_ended_and_the_exit_status_follows_the_childs_code()
|
|||
|
||||
// ---- the real child -----------------------------------------------------------
|
||||
|
||||
#[test]
|
||||
fn unreadable_and_foreign_lines_are_skipped_and_never_printed() {
|
||||
let canary = "canary-stream-line-8c41";
|
||||
let mut foreign: Value = serde_json::from_str(&init_line()).unwrap();
|
||||
foreign["cwd"] = json!(canary);
|
||||
foreign["type"] = json!(canary);
|
||||
let ran = go(vec![
|
||||
Out(format!("not json {canary}")),
|
||||
Out(foreign.to_string()),
|
||||
Out(format!("[\"{canary}\"]")),
|
||||
Out(at("m1", 10)),
|
||||
Out(result_line()),
|
||||
]);
|
||||
assert_eq!(ran.out, "request 1 prefix 10
|
||||
result subtype=success is_error=true: Failed to authenticate: OAuth session expired and could not be refreshed
|
||||
");
|
||||
let outcome = ran.outcome.as_ref().unwrap().to_string();
|
||||
assert!(!ran.out.contains(canary) && !outcome.contains(canary));
|
||||
assert!(!ran.written().iter().any(|text| text.contains(canary)), "nothing from the stream is written back");
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
mod process {
|
||||
mod lease_child;
|
||||
|
|
@ -1107,6 +1231,34 @@ mod process {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_whole_run_through_the_real_child_flushes_at_the_ceiling_and_ends_on_the_result() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let lines = [at("m1", 10), at("m2", CEILING_TOKENS)].join("
|
||||
");
|
||||
let result = result_line();
|
||||
// Prints two requests, waits for the flush on stdin, then the result, as a stand-in for a Self that obeys.
|
||||
let body = format!("cat <<'EOF'
|
||||
{lines}
|
||||
EOF
|
||||
read -t 5 start
|
||||
read -t 5 flush
|
||||
cat <<'EOF'
|
||||
{result}
|
||||
EOF
|
||||
while read more; do :; done
|
||||
exit 0");
|
||||
let program = script(&dir, &body);
|
||||
let mind = with_run();
|
||||
let mut out = Vec::new();
|
||||
let outcome = carry(&Seen::of(&mind), &SystemClock, &FakeLender::new(Answer::Grant), &Spawn(program), TEST_CAP_S, &mut out).unwrap();
|
||||
assert_eq!(outcome, SelfRunOutcome::Ended { cause: Cause::FlushRequested, code: Some(0), requests: 2, prefix: 300_000 });
|
||||
assert_eq!(String::from_utf8(out).unwrap(), "request 1 prefix 10
|
||||
request 2 prefix 300000
|
||||
result subtype=success is_error=true: Failed to authenticate: OAuth session expired and could not be refreshed
|
||||
");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_failure_result_before_any_request_closes_stdin_and_ends_the_run_promptly_through_the_real_child() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
|
|
|
|||
|
|
@ -69,7 +69,6 @@ fn malformed_commands_are_refused_and_write_nothing() {
|
|||
&["--instance", "eureka"],
|
||||
&["--instance", "eureka", "brake"],
|
||||
&["--instance", "eureka", "brake", "toggle"],
|
||||
&["--instance", "eureka", "dial", "set", "--heat", "1"],
|
||||
&["--instance", "../evil", "brake", "release"],
|
||||
&["--instances", "eureka", "brake", "release"],
|
||||
&["eureka", "eureka", "brake", "release"],
|
||||
|
|
@ -187,9 +186,10 @@ fn check_refuses_every_reading_but_released() {
|
|||
held(root.path(), "BrakeHeld");
|
||||
go(root.path(), &["--instance", "eureka", "brake", "release"], "op", 2).0.unwrap();
|
||||
held(root.path(), "BrakeAbsent");
|
||||
go(root.path(), &["swarm", "brake", "release"], "op", 3).0.unwrap();
|
||||
held(root.path(), "DialAbsent");
|
||||
// DialOutOfBounds cannot be written through the CLI: it is pinned in the crate's own tests.
|
||||
go(root.path(), &["swarm", "brake", "hold"], "op", 3).0.unwrap();
|
||||
held(root.path(), "BrakeHeld");
|
||||
go(root.path(), &["swarm", "brake", "release"], "op", 4).0.unwrap();
|
||||
check_out(root.path()).0.unwrap();
|
||||
// An undecodable store is a held reading too.
|
||||
let broken = tempfile::tempdir().unwrap();
|
||||
std::fs::create_dir(broken.path().join("eureka")).unwrap();
|
||||
|
|
@ -215,7 +215,7 @@ fn check_holds_for_the_named_instance_with_a_released_prefix_neighbour() {
|
|||
let root = tempfile::tempdir().unwrap();
|
||||
go(root.path(), &["--instance", "eureka", "brake", "hold"], "op", 0).0.unwrap();
|
||||
go(root.path(), &["swarm", "brake", "release"], "op", 0).0.unwrap();
|
||||
// Neighbours that share the held instance's text as a prefix, or only an edge of it, are released with a dial.
|
||||
// Neighbours that share the held instance's text as a prefix, or only an edge of it, are released.
|
||||
for (i, neighbour) in ["eureka-two", "eureka2", "xeureka"].into_iter().enumerate() {
|
||||
let at = 1 + 2 * i as i64;
|
||||
go(root.path(), &["--instance", neighbour, "brake", "release"], "op", at).0.unwrap();
|
||||
|
|
@ -281,7 +281,6 @@ fn only_brake_hold_calls_the_stopper() {
|
|||
&["--instance", "eureka", "show"],
|
||||
&["--instance", "eureka", "brake"],
|
||||
&["--instance", "eureka", "brake", "toggle"],
|
||||
&["swarm", "dial", "set", "--heat", "99", "--base-rate", "4", "--base-run", "1", "--k", "2"],
|
||||
&["--instance", "../evil", "brake", "release"],
|
||||
&["--instance", "eureka", "brake", "hold", "now"],
|
||||
&[],
|
||||
|
|
@ -470,14 +469,6 @@ fn swarm_commands_refuse_bad_input_and_write_nothing() {
|
|||
let root = tempfile::tempdir().unwrap();
|
||||
for args in [
|
||||
&["swarm"][..],
|
||||
&["swarm", "dial", "set", "--heat", "1"],
|
||||
&["swarm", "dial", "set", "--heat", "3", "--base-rate", "4", "--base-run", "2", "--k", "3"],
|
||||
&["swarm", "dial", "set", "--heat", "1", "--base-rate", "4", "--base-run", "2", "--k", "0"],
|
||||
&["swarm", "dial", "set", "--heat", "1", "--heat", "1", "--base-rate", "4", "--base-run", "2", "--k", "3"],
|
||||
&["swarm", "share", "set", "weksa", "0"],
|
||||
&["swarm", "share", "set", "weksa", "heavy"],
|
||||
&["swarm", "share", "set", "Not A Slug", "1"],
|
||||
&["swarm", "share", "set", "weksa"],
|
||||
&["swarm", "brake", "release", "now"],
|
||||
] {
|
||||
assert!(go(root.path(), args, "op", 0).0.is_err(), "{args:?} was accepted");
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ mind_body: mod lease_client
|
|||
mind_body: mod persona
|
||||
mind_body: mod queue
|
||||
mind_body: mod self_run
|
||||
mind_body: mod tempo
|
||||
mind_body::chat_client: # [derive (Clone , Copy , Debug , PartialEq , Eq)] pub enum Refusal { Brake , PersonaMismatch , UnknownRoom , EmptyText , SendFailed , UnknownPersona , }
|
||||
mind_body::chat_client: const ACK : & str
|
||||
mind_body::chat_client: const PENDING : & str
|
||||
|
|
@ -43,22 +44,18 @@ mind_body::cli: fn run (args : & [String] , root : & Path , set_by : & str , now
|
|||
mind_body::connector: const MAX_OUTPUT_TOKENS : u32
|
||||
mind_body::connector: fn endpoint (text : & str) -> Result < SocketAddr >
|
||||
mind_body::connector: fn key (key_file_text : & str) -> String
|
||||
mind_body::connector: fn render_plan (windows : & [PlanQuota] , now_ms : u64) -> String
|
||||
mind_body::connector: impl Connector for KitConnector
|
||||
mind_body::connector: impl KitConnector
|
||||
mind_body::connector: impl KitConnector: fn new (endpoint : SocketAddr , key_text : & str , model : impl Into < String > , caller : impl Into < String >) -> Result < Self >
|
||||
mind_body::connector: struct KitConnector pub-fields[]
|
||||
mind_body::control: # [derive (Clone , Copy , Debug , PartialEq , Eq)] pub enum HeldReason { BrakeAbsent , BrakeHeld , DialAbsent , DialOutOfBounds , HeatZero , ShareOutOfBounds , Undecodable , }
|
||||
mind_body::control: # [derive (Clone , Copy , Debug , PartialEq , Eq)] pub enum HeldReason { BrakeAbsent , BrakeHeld , Undecodable , }
|
||||
mind_body::control: # [derive (Debug , PartialEq , Eq)] pub enum Effective { Held { reason : HeldReason } , Released (Grant) , }
|
||||
mind_body::control: # [derive (Debug , PartialEq , Eq)] pub enum SwarmEffective { Held (HeldReason) , Released (Envelope) , }
|
||||
mind_body::control: # [derive (Debug , PartialEq , Eq)] pub enum SwarmEffective { Held (HeldReason) , Released , }
|
||||
mind_body::control: const BRAKE_KEY : & str
|
||||
mind_body::control: const CONTROL_ROOT : & str
|
||||
mind_body::control: const DIAL_KEY : & str
|
||||
mind_body::control: const K_MAX : u32
|
||||
mind_body::control: const SWARM_FILE : & str
|
||||
mind_body::control: fn base_rate_max () -> Decimal
|
||||
mind_body::control: fn base_run_max () -> Decimal
|
||||
mind_body::control: fn control_path (root : & Path , instance : & Slug) -> Result < PathBuf >
|
||||
mind_body::control: fn heat_max () -> Decimal
|
||||
mind_body::control: fn load_state (source : & impl ControlSource) -> Result < ControlState >
|
||||
mind_body::control: fn load_swarm_state (source : & impl ControlSource) -> Result < SwarmState >
|
||||
mind_body::control: fn read_effective (instance : & Slug) -> Effective
|
||||
|
|
@ -69,81 +66,54 @@ mind_body::control: impl ControlState
|
|||
mind_body::control: impl ControlWriter
|
||||
mind_body::control: impl ControlWriter: fn open (path : impl Into < PathBuf >) -> Result < Self >
|
||||
mind_body::control: impl ControlWriter: fn set_brake (& mut self , released : bool , set_at : DateTime < Utc > , set_by : & str) -> Result < () >
|
||||
mind_body::control: impl Envelope
|
||||
mind_body::control: impl Envelope: fn grant_for (& self , instance : & Slug , instance_effective : & Effective , budget_usd : Decimal) -> Option < Grant >
|
||||
mind_body::control: impl Envelope: fn k (& self) -> u32
|
||||
mind_body::control: impl Envelope: fn rate_usd_per_h (& self) -> Decimal
|
||||
mind_body::control: impl Envelope: fn run_cap_usd (& self) -> Decimal
|
||||
mind_body::control: impl Envelope: fn share (& self , instance : & Slug) -> Decimal
|
||||
mind_body::control: impl FileSource
|
||||
mind_body::control: impl FileSource: fn new (path : impl Into < PathBuf >) -> Self
|
||||
mind_body::control: impl Grant
|
||||
mind_body::control: impl Grant: fn instance (& self) -> & Slug
|
||||
mind_body::control: impl Grant: fn run_cap_usd (& self) -> Decimal
|
||||
mind_body::control: impl Share
|
||||
mind_body::control: impl Share: fn in_bounds (& self) -> bool
|
||||
mind_body::control: impl SwarmDial
|
||||
mind_body::control: impl SwarmDial: fn in_bounds (& self) -> bool
|
||||
mind_body::control: impl SwarmState
|
||||
mind_body::control: impl SwarmWriter
|
||||
mind_body::control: impl SwarmWriter: fn open (path : impl Into < PathBuf >) -> Result < Self >
|
||||
mind_body::control: impl SwarmWriter: fn set_brake (& mut self , released : bool , set_at : DateTime < Utc > , set_by : & str) -> Result < () >
|
||||
mind_body::control: impl SwarmWriter: fn set_dial (& mut self , dial : SwarmDial) -> Result < () >
|
||||
mind_body::control: impl SwarmWriter: fn set_share (& mut self , share : Share) -> Result < () >
|
||||
mind_body::control: impl std :: error :: Error for UnsafeStore
|
||||
mind_body::control: impl std :: fmt :: Display for UnsafeStore
|
||||
mind_body::control: pub trait ControlSource { fn snapshot (& self) -> Result < Vec < CultCacheEnvelope > > ; }
|
||||
mind_body::control: struct Brake # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[released: bool, set_at: DateTime < Utc >, set_by: String]
|
||||
mind_body::control: struct ControlState # [derive (Clone , Debug , PartialEq , Eq , Default)] pub-fields[brake: Option < Brake >]
|
||||
mind_body::control: struct ControlWriter pub-fields[]
|
||||
mind_body::control: struct Envelope # [derive (Debug , PartialEq , Eq)] pub-fields[]
|
||||
mind_body::control: struct FileSource pub-fields[]
|
||||
mind_body::control: struct Grant # [derive (Debug , PartialEq , Eq)] pub-fields[]
|
||||
mind_body::control: struct Share # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[instance: String, weight: Decimal]
|
||||
mind_body::control: struct SwarmDial # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[heat: Decimal, base_rate_usd_per_h: Decimal, base_run_usd: Decimal, k: u32, set_at: DateTime < Utc >, set_by: String]
|
||||
mind_body::control: struct SwarmState # [derive (Clone , Debug , PartialEq , Eq , Default)] pub-fields[brake: Option < Brake >, dial: Option < SwarmDial >, shares: Vec < Share >]
|
||||
mind_body::control: struct SwarmState # [derive (Clone , Debug , PartialEq , Eq , Default)] pub-fields[brake: Option < Brake >]
|
||||
mind_body::control: struct SwarmWriter pub-fields[]
|
||||
mind_body::control: struct UnsafeStore # [derive (Debug)] pub-fields[path: PathBuf, mode: u32, uid: u32]
|
||||
mind_body::heartbeat: # [derive (Clone , Debug , PartialEq , Eq)] pub enum Outcome { Held (HeldReason) , Polled { launched : Vec < Slug > , } , }
|
||||
mind_body::heartbeat: const AGENT : & str
|
||||
mind_body::heartbeat: const CLASSIFIER_CALLER : & str
|
||||
mind_body::heartbeat: fn poll (organs : & Organs , config : & Config) -> Result < Outcome >
|
||||
mind_body::heartbeat: fn store_classifier_config (path : impl Into < PathBuf > , config : & ClassifierConfig) -> Result < () >
|
||||
mind_body::heartbeat: impl ClassifierConfig
|
||||
mind_body::heartbeat: impl ClassifierConfig: fn standard () -> Self
|
||||
mind_body::heartbeat: impl ClassifierConfig: fn validate (& self) -> Result < () >
|
||||
mind_body::heartbeat: impl Config
|
||||
mind_body::heartbeat: impl Config: fn new (personas : Vec < PersonaId > , operators : Vec < String >) -> Result < Self >
|
||||
mind_body::heartbeat: impl Control for FileControl
|
||||
mind_body::heartbeat: impl FileStore
|
||||
mind_body::heartbeat: impl FileStore: fn check (& self) -> Result < () >
|
||||
mind_body::heartbeat: impl FileStore: fn new (path : impl Into < PathBuf >) -> Self
|
||||
mind_body::heartbeat: impl FileTunables
|
||||
mind_body::heartbeat: impl FileTunables: fn new (path : impl Into < PathBuf >) -> Self
|
||||
mind_body::heartbeat: impl Initiative
|
||||
mind_body::heartbeat: impl Models for KitConnector
|
||||
mind_body::heartbeat: impl MindRead
|
||||
mind_body::heartbeat: impl PersonaId
|
||||
mind_body::heartbeat: impl PersonaId: fn parse (spec : & str) -> Result < Self >
|
||||
mind_body::heartbeat: impl Row < '_ >
|
||||
mind_body::heartbeat: impl Store for FileStore
|
||||
mind_body::heartbeat: impl Tunables for FileTunables
|
||||
mind_body::heartbeat: impl TempoView for FileStore
|
||||
mind_body::heartbeat: impl fmt :: Display for Outcome
|
||||
mind_body::heartbeat: impl fmt :: Display for PollTrace
|
||||
mind_body::heartbeat: pub trait Control { fn envelope (& self) -> SwarmEffective ; fn effective (& self , instance : & Slug) -> Effective ; }
|
||||
mind_body::heartbeat: pub trait Models { fn classify (& self , request : & TurnRequest) -> Result < String > ; fn spent (& self , caller : & str) -> Result < Spend > ; }
|
||||
mind_body::heartbeat: pub trait Store { fn load (& self , instance : & Slug) -> Result < Option < Initiative > > ; fn save (& self , instance : & Slug , initiative : & Initiative) -> Result < () > ; fn record (& self , trace : & PollTrace) -> Result < () > ; fn latest (& self) -> Result < Option < PollTrace > > ; }
|
||||
mind_body::heartbeat: pub trait Tunables { fn classifier (& self) -> Result < ClassifierConfig > ; }
|
||||
mind_body::heartbeat: struct BurnTrace # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[run: String, spend_usd: Decimal, source: String]
|
||||
mind_body::heartbeat: struct ClassifierConfig # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[instructions: String, show_idle: bool, show_urgency: bool, show_completions: bool, urgency_min: Decimal, urgency_max: Decimal, urgency_ttl_s: u32]
|
||||
mind_body::heartbeat: pub trait Store { fn load (& self) -> Result < Option < HeartbeatState > > ; fn save (& self , state : & HeartbeatState) -> Result < () > ; fn record (& self , trace : & PollTrace) -> Result < () > ; }
|
||||
mind_body::heartbeat: pub trait TempoView { fn latest (& self) -> Result < Option < PollTrace > > ; }
|
||||
mind_body::heartbeat: struct Config # [derive (Clone , Debug , PartialEq , Eq)] pub-fields[personas: Vec < PersonaId >, operators: Vec < String >]
|
||||
mind_body::heartbeat: struct FileControl pub-fields[]
|
||||
mind_body::heartbeat: struct FileStore pub-fields[]
|
||||
mind_body::heartbeat: struct FileTunables pub-fields[]
|
||||
mind_body::heartbeat: struct Initiative # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[initiative_usd: Decimal, as_of: DateTime < Utc >, urgency: Decimal, urgency_at: DateTime < Utc >, last_burned_run: String, filled_events: Vec < String >, classified_seq: String, launched_run: String, launch_spend_usd: Decimal, launch_spend_known: bool, completions_through: String, launch_window: u64]
|
||||
mind_body::heartbeat: struct InstanceTrace # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[instance: String, initiative_usd: Decimal, rate_usd_per_h: Decimal, urgency: Decimal, urgency_age_s: i64, busy: bool, released: bool, crossing_at: String, waited_s: i64, idle_s: i64, filled_by: String, fill_reason: String, note: String]
|
||||
mind_body::heartbeat: struct Organs< 'a > pub-fields[seats: & 'a [Seat < 'a >], control: & 'a dyn Control, models: & 'a dyn Models, tunables: & 'a dyn Tunables, launcher: & 'a dyn Launcher, clock: & 'a dyn Clock, host: & 'a str, store: & 'a dyn Store]
|
||||
mind_body::heartbeat: struct HeartbeatState # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[last_beat_at: DateTime < Utc >, handled_mentions: Vec < String >]
|
||||
mind_body::heartbeat: struct InstanceTrace # [derive (Clone , Debug , PartialEq , Eq , serde :: Serialize , serde :: Deserialize)] pub-fields[instance: String, vote_beat_s: Option < u32 >, urgency_permille: u16, addressed: bool, busy: bool, released: bool, idle_s: i64, score: String, note: String]
|
||||
mind_body::heartbeat: struct Organs< 'a > pub-fields[seats: & 'a [Seat < 'a >], control: & 'a dyn Control, launcher: & 'a dyn Launcher, clock: & 'a dyn Clock, host: & 'a str, store: & 'a dyn Store]
|
||||
mind_body::heartbeat: struct PersonaId # [derive (Clone , Debug , PartialEq , Eq)] pub-fields[slug: Slug, public_name: String, handle: String, matrix_id: String, huginn: SocketAddr]
|
||||
mind_body::heartbeat: struct PollTrace # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[at: DateTime < Utc >, instances: Vec < InstanceTrace >, launches: Vec < String >, burns: Vec < BurnTrace >, classifier: String]
|
||||
mind_body::heartbeat: struct PollTrace # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[at: DateTime < Utc >, tempo_s: u32, instances: Vec < InstanceTrace >, launches: Vec < String >]
|
||||
mind_body::heartbeat: struct Seat< 'a > pub-fields[who: PersonaId, mind: & 'a dyn MindPort, chat: & 'a dyn Chat]
|
||||
mind_body::heartbeat: struct Spend # [derive (Clone , Copy , Debug , PartialEq , Eq)] pub-fields[usd: Decimal, window: u64]
|
||||
mind_body::launch: # [derive (Clone , Debug , PartialEq , Eq)] pub enum Declined { Admission (MindRefusal) , Conflict , AlreadyAdmitted , StartFailed , GrantForOtherInstance , PersonaRunTakesNoClaims , }
|
||||
mind_body::launch: # [derive (Clone , Debug , PartialEq , Eq)] pub enum LaunchOutcome { Launched { run : PipelineRef , } , NotQueued { item : PipelineRef , } , Tripped { item : PipelineRef , question : PipelineRef , } , Busy { run : PipelineRef , } , Refused (Declined) , }
|
||||
mind_body::launch: const START_GRACE_S : i64
|
||||
|
|
@ -164,7 +134,7 @@ mind_body::launch: struct Ports< 'a > pub-fields[mind: & 'a dyn MindPort, launc
|
|||
mind_body::launch: struct SystemClock pub-fields[]
|
||||
mind_body::launch: struct SystemctlReply pub-fields[success: bool, code: Option < i32 >, stdout: String]
|
||||
mind_body::launch: struct SystemdLauncher pub-fields[]
|
||||
mind_body::lease_client: # [derive (Clone , Copy , Debug , PartialEq , Eq , Serialize , Deserialize)] pub enum LeaseRefusalKind { SpendCeiling , CostBound , UnknownCaller , Expired , Busy , }
|
||||
mind_body::lease_client: # [derive (Clone , Copy , Debug , PartialEq , Eq , Serialize , Deserialize)] pub enum LeaseRefusalKind { UnknownCaller , Expired , Busy , ProviderRejected , }
|
||||
mind_body::lease_client: const LEASE_SOCKET_VARIABLE : & str
|
||||
mind_body::lease_client: const MAX_LEASE_FRAME_BYTES : usize
|
||||
mind_body::lease_client: impl Inheritable
|
||||
|
|
@ -176,28 +146,23 @@ mind_body::lease_client: impl TokenFd
|
|||
mind_body::lease_client: impl TokenFd: fn inheritable (& self) -> Result < Inheritable >
|
||||
mind_body::lease_client: impl std :: fmt :: Debug for TokenFd
|
||||
mind_body::lease_client: pub enum Lent { Granted (Box < dyn Lease >) , Refused (LeaseRefused) , }
|
||||
mind_body::lease_client: pub trait Lease { fn token (& self) -> & TokenFd ; fn settle (self : Box < Self > , settlement : Settlement) -> Result < u64 > ; }
|
||||
mind_body::lease_client: pub trait Lease { fn token (& self) -> & TokenFd ; fn plan_quota (& self) -> & [PlanQuota] ; }
|
||||
mind_body::lease_client: pub trait Lender { fn lend (& self , request : & LeaseRequest) -> Result < Lent > ; }
|
||||
mind_body::lease_client: struct Inheritable pub-fields[]
|
||||
mind_body::lease_client: struct LeaseRefused # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[kind: LeaseRefusalKind, detail: String]
|
||||
mind_body::lease_client: struct LeaseRequest # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[expires_at_unix_ms: u64]
|
||||
mind_body::lease_client: struct ModelUsage # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[model: String, usage: TokenUsage]
|
||||
mind_body::lease_client: struct Settlement # [derive (Clone , Debug , Default , PartialEq , Eq)] pub-fields[usage: Vec < ModelUsage >]
|
||||
mind_body::lease_client: struct SocketLender pub-fields[]
|
||||
mind_body::lease_client: struct TokenFd pub-fields[]
|
||||
mind_body::lease_client: struct TokenUsage # [derive (Clone , Debug , Default , PartialEq , Eq , Serialize , Deserialize)] pub-fields[input_tokens: u64, cache_read_tokens: u64, cache_write_tokens: u64, output_tokens: u64, reasoning_tokens: Option < u64 >]
|
||||
mind_body::lease_client::socket: impl Lease for Granted
|
||||
mind_body::persona: # [derive (Clone , Copy , Debug , PartialEq , Eq)] pub enum Failure { Held (HeldReason) , Chat , Persona , Doctrine , DoctrineTooLarge , Readout , Connector , Undecodable , RoomNotAllowed , Send , SelfRun , Ack , }
|
||||
mind_body::persona: # [derive (Clone , Copy , Debug , PartialEq , Eq)] pub enum Failure { Held (HeldReason) , Chat , Persona , Doctrine , DoctrineTooLarge , Connector , Undecodable , RoomNotAllowed , Send , SelfRun , Pulse , Ack , }
|
||||
mind_body::persona: # [derive (Debug , PartialEq , Eq)] pub enum Outcome { Dead (HeldReason) , NoRun , Served { run : PipelineRef , answered : u32 , failure : Option < Failure > , self_run : Option < PipelineRef > } , }
|
||||
mind_body::persona: const AGENT : & str
|
||||
mind_body::persona: const DOCTRINE_MAX_BYTES : usize
|
||||
mind_body::persona: const ENV_BURN_ROOM : & str
|
||||
mind_body::persona: const ENV_DOCTRINE : & str
|
||||
mind_body::persona: const ENV_OPERATOR : & str
|
||||
mind_body::persona: const ENV_ROOMS : & str
|
||||
mind_body::persona: const ENV_SELF_SENDER : & str
|
||||
mind_body::persona: const MAX_TURNS_PER_START : u32
|
||||
mind_body::persona: fn burn_line (readout : & SpendReadout , caller : & str , heat : Option < Decimal > , live_runs : usize) -> Option < String >
|
||||
mind_body::persona: fn reply_schema (rooms : & [String] , campaigns : & [String]) -> String
|
||||
mind_body::persona: fn start (organs : & Organs , control : & impl ControlSource , swarm : & impl ControlSource , config : & Config) -> Result < Outcome >
|
||||
mind_body::persona: impl Config
|
||||
|
|
@ -213,19 +178,19 @@ mind_body::persona: impl Trace for FileTrace
|
|||
mind_body::persona: impl Trace for Noted < '_ >
|
||||
mind_body::persona: impl fmt :: Display for Failure
|
||||
mind_body::persona: impl fmt :: Display for Outcome
|
||||
mind_body::persona: pub trait Connector { fn turn (& self , request : & TurnRequest) -> Result < String > ; fn spend_readout (& self) -> Result < SpendReadout > ; }
|
||||
mind_body::persona: pub trait Connector { fn turn (& self , request : & TurnRequest) -> Result < String > ; fn usage_readout (& self) -> Result < UsageReadout > ; }
|
||||
mind_body::persona: pub trait PersonaState { fn instructions (& self) -> Result < String > ; }
|
||||
mind_body::persona: pub trait Trace { fn record (& self , trace : & TurnTrace) -> Result < () > ; }
|
||||
mind_body::persona: pub use model_connector :: { CallerSpend , PlanQuota , SpendReadout } ;
|
||||
mind_body::persona: struct Config # [derive (Clone , Debug , PartialEq , Eq)] pub-fields[rooms: Vec < String >, burn_room: String, operators: Vec < String >, own_sender: String, max_turns: u32, doctrine: Vec < PathBuf >]
|
||||
mind_body::persona: pub use model_connector :: { PlanQuota , UsageReadout } ;
|
||||
mind_body::persona: struct Config # [derive (Clone , Debug , PartialEq , Eq)] pub-fields[rooms: Vec < String >, operators: Vec < String >, own_sender: String, max_turns: u32, doctrine: Vec < PathBuf >]
|
||||
mind_body::persona: struct FileTrace pub-fields[]
|
||||
mind_body::persona: struct HuginnPersona pub-fields[]
|
||||
mind_body::persona: struct Organs< 'a > pub-fields[mind: & 'a dyn MindPort, launcher: & 'a dyn Launcher, clock: & 'a dyn Clock, host: & 'a str, chat: & 'a dyn Chat, connector: & 'a dyn Connector, persona: & 'a dyn PersonaState, trace: & 'a dyn Trace]
|
||||
mind_body::persona: struct PersonaReply # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[say: Vec < Say >, start_self_run: Option < StartSelfRun >]
|
||||
mind_body::persona: struct Organs< 'a > pub-fields[mind: & 'a dyn MindPort, launcher: & 'a dyn Launcher, clock: & 'a dyn Clock, host: & 'a str, chat: & 'a dyn Chat, connector: & 'a dyn Connector, persona: & 'a dyn PersonaState, trace: & 'a dyn Trace, tempo: Option < & 'a dyn TempoView >]
|
||||
mind_body::persona: struct PersonaReply # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[say: Vec < Say >, start_self_run: Option < StartSelfRun >, tempo_vote_beat_s: Option < u32 >, urgency_permille: Option < u16 >]
|
||||
mind_body::persona: struct Say # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[room: String, text: String]
|
||||
mind_body::persona: struct StartSelfRun # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[brief: String, repo: String, campaign: String]
|
||||
mind_body::persona: struct TraceItem # [derive (Clone , Debug , PartialEq , Eq , Serialize , Deserialize)] pub-fields[provenance: String, room: String, text: String]
|
||||
mind_body::persona: struct TurnRequest # [derive (Clone , Debug , PartialEq , Eq)] pub-fields[caller: String, request_id: String, max_cost_micro_usd: u64, instructions: String, input: String, output_schema_json: String]
|
||||
mind_body::persona: struct TurnRequest # [derive (Clone , Debug , PartialEq , Eq)] pub-fields[caller: String, request_id: String, instructions: String, input: String, output_schema_json: String]
|
||||
mind_body::persona: struct TurnTrace # [derive (Clone , Debug , PartialEq , Eq , DatabaseEntry)] pub-fields[run: String, turn: u32, at: DateTime < Utc >, inputs: Vec < TraceItem >, outputs: Vec < TraceItem >, outcome: String]
|
||||
mind_body::queue: # [derive (Clone , Copy , Debug , PartialEq , Eq)] pub enum Breaker { Clear , Trip , }
|
||||
mind_body::queue: const CONSECUTIVE : usize
|
||||
|
|
@ -257,23 +222,30 @@ mind_body::self_run: const SCRATCH_VARIABLE : & str
|
|||
mind_body::self_run: const SEED_VARIABLE : & str
|
||||
mind_body::self_run: const SESSION_NAMESPACE : Uuid
|
||||
mind_body::self_run: fn carry (mind : & dyn MindPort , clock : & dyn Clock , lender : & dyn Lender , spawner : & dyn Spawner , run_cap_s : u64 , out : & mut dyn Write) -> Result < SelfRunOutcome >
|
||||
mind_body::self_run: fn claude_args (session : Uuid , budget_usd : & str) -> Vec < String >
|
||||
mind_body::self_run: fn claude_args (session : Uuid) -> Vec < String >
|
||||
mind_body::self_run: fn read_usage (line : & str) -> Usage
|
||||
mind_body::self_run: fn session_id (run : & PipelineRef) -> Uuid
|
||||
mind_body::self_run: fn start_message (instance : & Slug , run : & PipelineRef) -> String
|
||||
mind_body::self_run: fn start_message (instance : & Slug , run : & PipelineRef , plan_quota : & [PlanQuota] , now_ms : u64) -> String
|
||||
mind_body::self_run: impl Child for ClaudeProcess
|
||||
mind_body::self_run: impl ClaudeSpawner
|
||||
mind_body::self_run: impl ClaudeSpawner: fn new (unit_environment : impl IntoIterator < Item = (OsString , OsString) >) -> Result < Self >
|
||||
mind_body::self_run: impl Drop for FreshConfig
|
||||
mind_body::self_run: impl FreshConfig
|
||||
mind_body::self_run: impl Heard
|
||||
mind_body::self_run: impl SelfRunOutcome
|
||||
mind_body::self_run: impl SelfRunOutcome: fn exit_status (& self) -> i32
|
||||
mind_body::self_run: impl Spawner for ClaudeSpawner
|
||||
mind_body::self_run: impl Spent
|
||||
mind_body::self_run: impl Stop
|
||||
mind_body::self_run: impl fmt :: Display for SeedLinkRefused
|
||||
mind_body::self_run: impl std :: error :: Error for SeedLinkRefused
|
||||
mind_body::self_run: impl fmt :: Display for SelfRunOutcome
|
||||
mind_body::self_run: impl std :: error :: Error for SeedLinkRefused
|
||||
mind_body::self_run: pub trait Child { fn write_line (& mut self , line : & str) ; fn close_input (& mut self) ; fn next (& mut self , timeout : StdDuration) -> Read ; fn stop (& mut self , how : Stop) -> bool ; }
|
||||
mind_body::self_run: pub trait Spawner { fn spawn (& self , args : & [String] , token : & TokenFd) -> Result < Box < dyn Child > > ; }
|
||||
mind_body::self_run: struct ClaudeSpawner pub-fields[]
|
||||
mind_body::tempo: const DEFAULT_BEAT_S : u32
|
||||
mind_body::tempo: const LOG_BOUND_ORDERS : f64
|
||||
mind_body::tempo: fn pick (rows : & [Standing] , beat_s : u32) -> Option < usize >
|
||||
mind_body::tempo: fn score (standing : & Standing , beat_s : u32) -> f64
|
||||
mind_body::tempo: fn tally (votes : & [u32]) -> u32
|
||||
mind_body::tempo: fn urgency_permille (standing : & Standing) -> u16
|
||||
mind_body::tempo: struct Standing # [derive (Clone , Debug , PartialEq , Eq)] pub-fields[slug: String, eligible: bool, waited_s: Option < u64 >, last_turn_ms: Option < i64 >, self_permille: u16, topic_permille: u16, addressed_by_member: bool]
|
||||
|
|
|
|||
Loading…
Reference in a new issue