kcode-k1-chat-codex-codec 0.7.1

Native Codex wrapper validator and open-format K1 ChatBox projector
Documentation
use kcode_k1_chat_chatend::{
    AGENT_ATTACHMENT_TYPE, AGENT_MESSAGE_TYPE, AGENT_RESPONSE_TYPE, BoxId, ChatBox,
    SYSTEM_MESSAGE_TYPE, TOOL_ATTACHMENT_TYPE, TOOL_CALL_TYPE, TOOL_MESSAGE_TYPE, TOOL_RESULT_TYPE,
    USER_ATTACHMENT_TYPE, USER_MESSAGE_TYPE,
};
use kcode_k1_chat_codex_codec::{BoxValue, Call, Codec, open_agent_response, project};
use kcode_k1_codex_adapter::{BoxCodec, ToolCall};
use serde_json::json;

fn call(name: &str, arguments: serde_json::Value) -> ToolCall {
    ToolCall {
        call_id: "call".into(),
        name: name.into(),
        arguments,
    }
}

#[test]
fn validates_exact_wrapper_and_serializes_nested_arguments() {
    let mut codec = Codec;
    assert_eq!(
        codec.tool_call_box(&call(
            "call_ktool",
            json!({"name":"run","arguments":{"b":[2,1],"a":true}}),
        )),
        BoxValue::Call(Ok(Call {
            name: "run".into(),
            arguments: "{\"a\":true,\"b\":[2,1]}".into(),
        }))
    );
    assert_eq!(
        codec.tool_call_box(&call(
            "call_ktool",
            json!({"name":"nullable","arguments":null}),
        )),
        BoxValue::Call(Ok(Call {
            name: "nullable".into(),
            arguments: "null".into(),
        }))
    );
}

#[test]
fn malformed_native_calls_retain_validation_behavior() {
    let mut codec = Codec;
    let cases = [
        (
            "other",
            json!({"name":"x","arguments":null}),
            "tool name must be call_ktool or agent_message",
        ),
        ("call_ktool", json!([]), "tool arguments must be an object"),
        (
            "call_ktool",
            json!({"name":"x"}),
            "tool arguments must have name and arguments",
        ),
        (
            "call_ktool",
            json!({"arguments":null}),
            "tool arguments must have name and arguments",
        ),
        (
            "call_ktool",
            json!({"name":"x","arguments":1,"extra":true}),
            "tool arguments must have name and arguments",
        ),
        (
            "call_ktool",
            json!({"name":1,"arguments":null}),
            "tool arguments name must be a string",
        ),
    ];

    for (tool_name, arguments, error) in cases {
        assert_eq!(
            codec.tool_call_box(&call(tool_name, arguments)),
            BoxValue::Call(Err(error.into()))
        );
    }
}

#[test]
fn validates_agent_message_as_a_distinct_nondispatchable_action() {
    let mut codec = Codec;
    assert_eq!(
        codec.tool_call_box(&call("agent_message", json!({"message":"visible"}))),
        BoxValue::AgentMessage(Ok("visible".into()))
    );
    assert_eq!(
        codec.tool_call_box(&call("agent_message", json!({"message":"   "}))),
        BoxValue::AgentMessage(Ok("   ".into()))
    );

    let cases = [
        (json!([]), "agent_message arguments must be an object"),
        (
            json!({}),
            "agent_message arguments must have exactly one message field",
        ),
        (
            json!({"message":"visible","extra":true}),
            "agent_message arguments must have exactly one message field",
        ),
        (
            json!({"message":1}),
            "agent_message message must be a string",
        ),
        (
            json!({"message":""}),
            "agent_message message must not be empty",
        ),
    ];

    for (arguments, error) in cases {
        assert_eq!(
            codec.tool_call_box(&call("agent_message", arguments)),
            BoxValue::AgentMessage(Err(error.into()))
        );
    }
}

#[test]
fn projects_all_familiar_string_conventions_generically() {
    let box_types = [
        SYSTEM_MESSAGE_TYPE,
        USER_MESSAGE_TYPE,
        AGENT_RESPONSE_TYPE,
        AGENT_MESSAGE_TYPE,
        USER_ATTACHMENT_TYPE,
        AGENT_ATTACHMENT_TYPE,
        TOOL_CALL_TYPE,
        TOOL_MESSAGE_TYPE,
        TOOL_ATTACHMENT_TYPE,
        TOOL_RESULT_TYPE,
    ];

    for (index, box_type) in box_types.into_iter().enumerate() {
        let id = u64::try_from(index + 1).unwrap();
        let contents = format!("visible contents {id}");
        let box_ = ChatBox::new(
            BoxId::new(id),
            box_type.into(),
            contents.clone(),
            format!("hidden-type-{id}"),
            format!("hidden-contents-{id}"),
        );
        assert_eq!(
            project(&box_),
            BoxValue::History(format!("[Box {id} | {box_type}]\n{contents}"))
        );
    }
}

#[test]
fn preserves_unknown_type_and_literal_text_but_omits_hidden_markers() {
    let box_type = "Future\n\"Type\"\\v9";
    let contents = "first line\n\"quoted\" and \\backslash\nlast line";
    let box_ = ChatBox::new(
        BoxId::new(10),
        box_type.into(),
        contents.into(),
        "HIDDEN-TYPE-MARKER".into(),
        "HIDDEN-CONTENTS-MARKER\nsecret".into(),
    );

    let projected = project(&box_);
    assert_eq!(
        projected,
        BoxValue::History(format!("[Box 10 | {box_type}]\n{contents}"))
    );
    let BoxValue::History(text) = projected else {
        panic!("projection must be history");
    };
    assert!(!text.contains("HIDDEN-TYPE-MARKER"));
    assert!(!text.contains("HIDDEN-CONTENTS-MARKER"));
}

#[test]
fn renders_only_history_and_the_lf_terminated_open_response_header_as_model_text() {
    assert_eq!(Codec.box_text(&BoxValue::Call(Err("bad".into()))), "");
    assert_eq!(
        Codec.box_text(&BoxValue::AgentMessage(Ok("visible".into()))),
        ""
    );
    assert_eq!(
        Codec.box_text(&BoxValue::History("history".into())),
        "history"
    );
    assert_eq!(
        open_agent_response(BoxId::new(42)),
        BoxValue::History("[Box 42 | Agent Response]\n".into())
    );
}