kcode-k1-chat-codex-state 0.4.0

Deterministic open-format Codex K1 conversation state
Documentation
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")))
    );
}