use kcode_k1_chat_codex_codec::{BoxValue, Call, project};
use kcode_k1_chat_codex_state::{
AGENT_ATTACHMENT_TYPE, AGENT_MESSAGE_TYPE, ConversationState, RestartError,
SYSTEM_MESSAGE_TYPE, Start, Status, TOOL_ATTACHMENT_TYPE, TOOL_CALL_TYPE, TOOL_MESSAGE_TYPE,
TOOL_RESULT_TYPE, ToolCallId, USER_ATTACHMENT_TYPE, USER_MESSAGE_TYPE,
};
use kcode_k1_codex_adapter::{ShimItem, ShimOutput};
fn call() -> BoxValue {
BoxValue::Call(Ok(Call {
name: "tool".into(),
arguments: "{}".into(),
}))
}
fn accept(state: &mut ConversationState, kind: &str, contents: &str) {
state
.accept(kind.into(), contents.into(), String::new(), String::new())
.unwrap();
}
fn start(state: &mut ConversationState) -> Start {
state.begin().unwrap().unwrap()
}
fn active(byte: u8) -> (ConversationState, u64, ToolCallId) {
let mut state = ConversationState::new([byte; 12]);
accept(&mut state, USER_MESSAGE_TYPE, "ask");
let job = start(&mut state).job;
let id = state
.prepare_stage(job, "thinking".into(), vec![call()])
.unwrap()[0]
.tool_call_id;
(state, job, id)
}
#[test]
fn unknown_values_survive_start_steer_recovery_and_projection() {
let mut state = ConversationState::new([1; 12]);
state
.accept(
"Future Start".into(),
"start visible".into(),
"future/v9".into(),
"start hidden".into(),
)
.unwrap();
let first = start(&mut state);
assert_eq!(first.boxes, vec![project(&state.boxes()[0])]);
assert!(!format!("{:?}", first.boxes).contains("start hidden"));
let first_id = state
.prepare_stage(first.job, "thinking".into(), vec![call()])
.unwrap()[0]
.tool_call_id;
state
.accept(
"Future Steer".into(),
"steer visible".into(),
"future/v10".into(),
"steer hidden".into(),
)
.unwrap();
state
.accept_tool_return(first_id, Ok("returned".into()))
.unwrap();
let token = state.prepare_steer(first.job).unwrap().unwrap();
assert_eq!(
token.values(),
state.boxes()[3..5].iter().map(project).collect::<Vec<_>>()
);
assert_eq!(
(
state.boxes()[3].box_type(),
state.boxes()[3].hidden_type(),
state.boxes()[3].hidden_contents()
),
("Future Steer", "future/v10", "steer hidden")
);
assert_eq!(
state.boxes()[4]
.tool_result_metadata()
.unwrap()
.unwrap()
.tool_call_id,
first_id
);
let repeated = state.prepare_steer(first.job).unwrap().unwrap();
assert_eq!(repeated.values(), token.values());
state.commit_steer(repeated).unwrap();
assert!(state.commit_steer(token).is_err());
state
.complete(
first.job,
ShimOutput {
items: vec![ShimItem::Text("done".into())],
},
)
.unwrap();
let canonical = state.boxes().to_vec();
let expected = canonical.iter().map(project).collect::<Vec<_>>();
let mut recovered = ConversationState::recover([1; 12], canonical.clone(), true).unwrap();
assert_eq!(recovered.boxes(), canonical);
let retry = start(&mut recovered);
assert_eq!(retry.boxes, expected);
let next = recovered
.prepare_stage(retry.job, String::new(), vec![call()])
.unwrap()[0]
.tool_call_id;
assert!(next.sequence() > first_id.sequence());
}
#[test]
fn open_fifo_tokens_and_retry_frontier_remain_exact() {
let mut state = ConversationState::new([2; 12]);
accept(&mut state, USER_MESSAGE_TYPE, "ask");
let first = start(&mut state);
state
.accept(
"Future Retry".into(),
"visible".into(),
"future/retry".into(),
"hidden".into(),
)
.unwrap();
assert!(state.prepare_steer(first.job + 1).is_err());
let token = state.prepare_steer(first.job).unwrap().unwrap();
state.validate_steer(&token).unwrap();
state.fail(first.job, "before launch".into(), true);
assert!(matches!(
state.status(),
Status::Stalled {
restartable: true,
..
}
));
assert!(state.validate_steer(&token).is_err());
state.restart().unwrap();
let retry = start(&mut state);
assert_eq!(
retry.boxes,
state.boxes().iter().map(project).collect::<Vec<_>>()
);
assert!(matches!(&retry.boxes[1], BoxValue::History(text) if text.contains("Future Retry")));
state
.complete(retry.job, ShimOutput { items: vec![] })
.unwrap();
assert_eq!(state.status(), Status::Quiet);
}
#[test]
fn validation_stall_and_terminal_rules_hold() {
let mut malformed = ConversationState::new([3; 12]);
accept(&mut malformed, USER_MESSAGE_TYPE, "ask");
let job = start(&mut malformed).job;
assert!(
malformed
.prepare_stage(job, "bad".into(), vec![BoxValue::History("bad".into())])
.is_err()
);
assert_eq!(malformed.boxes().len(), 1);
malformed.fail(job, "early".into(), true);
malformed.restart().unwrap();
let (mut pending, job, _) = active(4);
accept(&mut pending, USER_MESSAGE_TYPE, "queued");
let token = pending.prepare_steer(job).unwrap().unwrap();
assert!(pending.complete(job, ShimOutput { items: vec![] }).is_err());
assert!(pending.validate_steer(&token).is_err());
assert_eq!(pending.restart(), Err(RestartError::NotRestartable));
let (mut terminal, job, _) = active(5);
let output = ShimOutput {
items: vec![ShimItem::Box(BoxValue::History("forbidden".into()))],
};
assert!(terminal.complete(job, output).is_err());
assert_eq!(terminal.restart(), Err(RestartError::NotRestartable));
}
#[test]
fn steer_tokens_are_process_local_and_exact_once() {
let (mut first, job, _) = active(6);
accept(&mut first, USER_MESSAGE_TYPE, "queued");
let token = first.prepare_steer(job).unwrap().unwrap();
let (mut other, other_job, _) = active(6);
accept(&mut other, USER_MESSAGE_TYPE, "queued");
let foreign = other.prepare_steer(other_job).unwrap().unwrap();
assert!(first.validate_steer(&foreign).is_err());
first.commit_steer(token.clone()).unwrap();
assert!(first.commit_steer(token).is_err());
}
#[test]
fn nine_names_remain_open_string_conveniences() {
let names = [
SYSTEM_MESSAGE_TYPE,
USER_MESSAGE_TYPE,
AGENT_MESSAGE_TYPE,
USER_ATTACHMENT_TYPE,
AGENT_ATTACHMENT_TYPE,
TOOL_CALL_TYPE,
TOOL_MESSAGE_TYPE,
TOOL_ATTACHMENT_TYPE,
TOOL_RESULT_TYPE,
];
assert_eq!(
names,
[
"System Message",
"User Message",
"Agent Message",
"User Attachment",
"Agent Attachment",
"Tool Call",
"Tool Message",
"Tool Attachment",
"Tool Result"
]
);
let mut state = ConversationState::new([7; 12]);
for (index, name) in names.into_iter().enumerate() {
state
.accept(
name.into(),
format!("visible {index}"),
format!("hidden/{index}"),
format!("secret {index}"),
)
.unwrap();
}
let projected = start(&mut state).boxes;
assert_eq!(
projected,
state.boxes().iter().map(project).collect::<Vec<_>>()
);
assert_eq!(state.boxes()[8].hidden_contents(), "secret 8");
assert!(
projected
.iter()
.all(|value| matches!(value, BoxValue::History(text) if !text.contains("secret")))
);
}