supercode-harness 0.4.10

The optional native Supercode agent and tool harness
Documentation
use std::collections::BTreeSet;
use std::future::Future;
use std::pin::Pin;
use std::sync::{Arc, Mutex};

use serde_json::Value;
use supercode_harness::{
    ChatMessage, FrontendEvent, FrontendFacadeMethod, FrontendFacadeTransport, FrontendRequest,
    FrontendResponse, FrontendRuntimeDescriptor, FrontendRuntimeError, GeneratedFrontendClient,
};

fn contract() -> Value {
    serde_json::from_str(include_str!("../../../sdk/frontend/contract.json")).unwrap()
}

fn conformance_fixture() -> Value {
    serde_json::from_str(include_str!(
        "../../../sdk/frontend/test/fixtures/conformance.json"
    ))
    .unwrap()
}

#[test]
fn generated_rust_catalog_is_exactly_the_language_neutral_v2_contract() {
    let contract = contract();
    assert_eq!(contract["schema"], "supercode.frontend.contract.v2");
    assert_eq!(contract["canonical_sdk"], "supercode.sdk.v1");
    let methods = contract["methods"].as_array().unwrap();
    assert_eq!(methods.len(), FrontendFacadeMethod::ALL.len());
    for (definition, generated) in methods.iter().zip(FrontendFacadeMethod::ALL) {
        assert_eq!(definition["id"], generated.id());
        assert_eq!(definition["wire"], generated.wire_name());
        assert_eq!(definition["sdk_action"], generated.sdk_action());
        assert_eq!(
            definition["transports"],
            serde_json::json!(["local", "http", "websocket", "acp"])
        );
        assert_eq!(
            FrontendFacadeMethod::from_wire_name(generated.wire_name()),
            Some(generated)
        );
    }

    for (alias, id) in contract["compatibility_aliases"].as_object().unwrap() {
        assert_eq!(
            FrontendFacadeMethod::from_wire_name(alias).map(FrontendFacadeMethod::id),
            id.as_str()
        );
    }
}

#[test]
fn contract_defines_every_wire_shape_without_language_specific_type_pointers() {
    fn visit(value: &Value) {
        match value {
            Value::Object(object) => {
                assert!(!object.contains_key("rust"));
                assert!(!object.contains_key("typescript"));
                for value in object.values() {
                    visit(value);
                }
            }
            Value::Array(values) => values.iter().for_each(visit),
            _ => {}
        }
    }

    let contract = contract();
    visit(&contract);
    let types = contract["types"].as_object().unwrap();
    for required in [
        "ChatMessage",
        "FrontendRuntimeDescriptor",
        "FrontendAttachSnapshot",
        "FrontendEvent",
        "FrontendRequest",
        "FrontendResponse",
        "FrontendError",
        "RuntimeLeaseSnapshot",
    ] {
        let definition = types
            .get(required)
            .unwrap_or_else(|| panic!("contract omitted {required}"));
        assert!(definition.get("kind").is_some(), "{required} has no shape");
    }
    assert_eq!(
        types["FrontendRequest"]["fields"]["payload"]["type"],
        "JsonValue"
    );
    assert_eq!(
        types["FrontendRuntimeDescriptor"]["fields"]["extensions"]["type"]["kind"],
        "map"
    );
    assert_eq!(
        contract["opaque_extensions"]["events"],
        "FrontendEvent.payload"
    );
}

struct GeneratedClientFixture {
    calls: Arc<Mutex<Vec<Value>>>,
}

impl FrontendFacadeTransport for GeneratedClientFixture {
    fn call<'a>(
        &'a self,
        method: FrontendFacadeMethod,
        params: Value,
    ) -> Pin<Box<dyn Future<Output = Result<Value, FrontendRuntimeError>> + Send + 'a>> {
        Box::pin(async move {
            self.calls.lock().unwrap().push(serde_json::json!({
                "method": method.wire_name(),
                "params": params,
            }));
            let fixture = conformance_fixture();
            match method {
                FrontendFacadeMethod::Describe => Ok(fixture["descriptor"].clone()),
                FrontendFacadeMethod::SendInput => {
                    if params["prompt"] == fixture["competing_prompt"] {
                        Err(supercode_harness::RuntimeSubmitError::Busy.into())
                    } else {
                        assert_eq!(params["prompt"], fixture["prompt"]);
                        Ok(serde_json::json!({"accepted":true}))
                    }
                }
                FrontendFacadeMethod::Attach => {
                    assert_eq!(params["limit"], 1000);
                    Ok(serde_json::json!({
                        "descriptor": fixture["descriptor"],
                        "history": fixture["history"]["messages"],
                        "history_cursor": fixture["history"]["cursor"],
                        "replay": fixture["replay"]
                    }))
                }
                FrontendFacadeMethod::Respond => {
                    if params["response"]["request_id"] == fixture["request"]["id"] {
                        Ok(serde_json::json!({"accepted":true}))
                    } else {
                        Err(FrontendRuntimeError::UnsupportedAction("respond"))
                    }
                }
                FrontendFacadeMethod::Detach => Ok(serde_json::json!({
                    "controller":null,"observers":[],"lease_ttl_ms":30000
                })),
                _ => Err(FrontendRuntimeError::UnsupportedAction(method.sdk_action())),
            }
        })
    }
}

#[tokio::test]
async fn generated_rust_client_is_typed_and_preserves_opaque_extensions() {
    let fixture = conformance_fixture();
    let calls = Arc::new(Mutex::new(Vec::new()));
    let client = GeneratedFrontendClient::new(GeneratedClientFixture {
        calls: calls.clone(),
    });
    let descriptor = client.describe().await.unwrap();
    assert_eq!(
        serde_json::to_value(&descriptor).unwrap(),
        fixture["descriptor"]
    );
    let attachment = client.attach(1000, Some(4)).await.unwrap();
    assert_eq!(attachment.history_cursor, 4);
    assert_eq!(
        serde_json::to_value(&attachment.history).unwrap(),
        fixture["history"]["messages"]
    );
    assert_eq!(
        serde_json::to_value(&attachment.replay).unwrap(),
        fixture["replay"]
    );
    assert_eq!(
        serde_json::to_value(&attachment.replay[0]).unwrap()["payload"]["request"],
        fixture["request"]
    );
    assert!(client
        .send_input(fixture["prompt"].as_str().unwrap().into(), None)
        .await
        .unwrap());
    let response =
        serde_json::from_value(fixture["semantic_actions"][3]["params"]["response"].clone())
            .unwrap();
    assert!(client.respond(response).await.unwrap());
    client.detach().await.unwrap();
    assert_eq!(
        *calls.lock().unwrap(),
        fixture["semantic_actions"].as_array().unwrap().clone()
    );

    let _ = client.attach(1000, None).await.unwrap();
    assert!(
        calls.lock().unwrap().last().unwrap()["params"]
            .get("after_sequence")
            .is_none(),
        "optional Rust params must be omitted rather than serialized as null"
    );
    let busy = client
        .send_input(fixture["competing_prompt"].as_str().unwrap().into(), None)
        .await
        .unwrap_err();
    let unsupported = serde_json::from_value(fixture["unsupported_response"].clone()).unwrap();
    let unsupported = client.respond(unsupported).await.unwrap_err();
    assert_eq!(
        serde_json::json!([busy.code(), unsupported.code()]),
        fixture["errors"]["observed"]
    );
}

#[test]
fn facade_covers_traced_needs_without_importing_private_client_protocols() {
    let contract = contract();
    let families = contract["traced_needs"]["families"]
        .as_array()
        .unwrap()
        .iter()
        .map(|value| value.as_str().unwrap())
        .collect::<BTreeSet<_>>();
    assert_eq!(
        families,
        BTreeSet::from([
            "capabilities",
            "cursor_replay",
            "history",
            "identity",
            "reconnect",
            "requests",
            "semantic_actions",
            "sequenced_events",
            "typed_errors",
        ])
    );
    let private = contract["traced_needs"]["excluded_private_protocols"]
        .as_array()
        .unwrap();
    assert_eq!(private.len(), 4);
    let method_bytes = serde_json::to_string(&contract["methods"]).unwrap();
    for name in private {
        assert!(!method_bytes.contains(name.as_str().unwrap()));
    }
    for forbidden_policy in [
        "provider_auth",
        "model_routing",
        "session_format",
        "reduction_policy",
        "scheduler_activation",
        "agent_start",
    ] {
        assert!(
            !method_bytes.contains(forbidden_policy),
            "facade selection leaked runtime policy `{forbidden_policy}`"
        );
    }

    let allowlist: Value = serde_json::from_str(include_str!(
        "../../../scripts/client-protocol-corpus/allowlist.json"
    ))
    .unwrap();
    assert_eq!(
        allowlist["schema"],
        "supercode.stock-client-required-methods.v1"
    );
    assert_eq!(
        contract["traced_needs"]["source"],
        "scripts/client-protocol-corpus/allowlist.json"
    );
}

#[test]
fn shared_binding_fixture_names_ordered_actions_events_and_errors() {
    let fixture = conformance_fixture();
    assert_eq!(fixture["schema"], "supercode.frontend.conformance.v2");
    assert_eq!(fixture["contract"], "supercode.frontend.contract.v2");
    assert_eq!(
        fixture["bindings"],
        serde_json::json!([
            "local_rust",
            "http_sse_rust",
            "websocket_rust",
            "acp_rust",
            "http_sse_typescript",
            "websocket_typescript"
        ])
    );
    assert_eq!(
        fixture["generated_call_surfaces"],
        serde_json::json!(["rust", "typescript"])
    );
    assert_eq!(fixture["session_id"], "stable-sdk-session");
    assert_eq!(fixture["errors"]["competing_input"], "busy");
    assert_eq!(
        fixture["errors"]["unsupported_response"],
        "unsupported_action"
    );
    assert_eq!(
        fixture["event_kinds"],
        serde_json::json!([
            "user_message",
            "turn_started",
            "text_delta",
            "usage",
            "turn_completed",
            "turn_succeeded"
        ])
    );
    assert_eq!(fixture["history"]["cursor"], 4);
    assert_eq!(fixture["replay"].as_array().unwrap().len(), 2);
    assert_eq!(fixture["live"].as_array().unwrap().len(), 2);
    assert_eq!(fixture["request"]["kind"], "approval");
    assert_eq!(
        fixture["descriptor"]["extensions"]["future_client_field"]["retained"],
        true
    );
    assert_eq!(
        fixture["semantic_actions"]
            .as_array()
            .unwrap()
            .iter()
            .map(|action| action["method"].as_str().unwrap())
            .collect::<Vec<_>>(),
        vec![
            "frontend.v2.describe",
            "frontend.v2.attach",
            "frontend.v2.send_input",
            "frontend.v2.respond",
            "frontend.v2.detach",
        ]
    );
    let contract_names = contract()["types"]["FrontendErrorName"]["values"]
        .as_array()
        .unwrap()
        .clone();
    assert_eq!(fixture["errors"]["named"], Value::Array(contract_names));

    let descriptor: FrontendRuntimeDescriptor =
        serde_json::from_value(fixture["descriptor"].clone()).unwrap();
    assert_eq!(
        descriptor.extensions["future_client_field"]["retained"],
        true
    );
    let history: Vec<ChatMessage> =
        serde_json::from_value(fixture["history"]["messages"].clone()).unwrap();
    assert_eq!(history.len(), 3);
    let request: FrontendRequest = serde_json::from_value(fixture["request"].clone()).unwrap();
    assert_eq!(request.id, 77);
    let replay: Vec<FrontendEvent> = serde_json::from_value(fixture["replay"].clone()).unwrap();
    assert_eq!(replay[0].payload["request"]["payload"], request.payload);
    let response: FrontendResponse =
        serde_json::from_value(fixture["semantic_actions"][3]["params"]["response"].clone())
            .unwrap();
    assert_eq!(serde_json::to_value(response).unwrap()["request_id"], 77);
}