gproxy-protocol 4.1.7

GPROXY v4 connection modelling, operation declarations, vendor wire types and pairwise conversion
Documentation
use super::*;

#[test]
fn foreign_chat_image_is_read_in_source_scope_and_sent_as_actual_gemini_bytes() {
    let access = Resources::png();
    let scope = "source-openai-principal".into();
    let resources = resources(&access, &scope);
    let store = Store::default();
    let state = state(&store, Dialect::Gemini);
    let mut request = input("h");
    request["messages"] = json!([{"role":"user","content":[{"type":"image_url","image_url":{"url":"https://source/private.png","foreign":"ignore"}}]}]);
    let mut p = ready(ChatViaGemini::prepare_with_capabilities(
        serde_json::from_value(request).unwrap(),
        endpoint(),
        ids(Dialect::OpenAiChat, Dialect::Gemini),
        &state,
        &resources,
        &Default::default(),
    ))
    .unwrap();
    let target = serde_json::to_value(p.target_request()).unwrap();
    assert_eq!(
        target["contents"][0]["parts"][0]["inlineData"]["mimeType"],
        "image/png"
    );
    assert!(target["contents"][0]["parts"][0].get("fileData").is_none());
    assert_eq!(access.reads.lock().unwrap()[0].0, scope);
    let host = Host::new(output("g"));
    let mut progress = GenerationProgress::default();
    ready(p.invoke(
        &host,
        &(),
        codec_limits(),
        &state,
        &mut progress,
        gemini_facts,
    ))
    .unwrap();
    assert_eq!(host.sent.lock().unwrap().len(), 1);
}

#[test]
fn three_other_source_dialects_materialize_declared_ids_and_uris() {
    let access = Resources::png();
    let scope = "source".into();
    let resources = resources(&access, &scope);
    let mut claude = input("c");
    claude["messages"] = json!([{"role":"user","content":[{"type":"image","source":{"type":"file","file_id":"actual-file"}}]}]);
    let claude = serde_json::to_value(
        ready(resources.claude(serde_json::from_value(claude).unwrap())).unwrap(),
    )
    .unwrap();
    assert_eq!(
        claude["messages"][0]["content"][0]["source"]["type"],
        "base64"
    );
    let mut gemini = input("g");
    gemini["contents"] = json!([{"role":"user","parts":[{"fileData":{"fileUri":"gs://actual/image","mimeType":"image/png"}}]}]);
    let gemini = serde_json::to_value(
        ready(resources.gemini(serde_json::from_value(gemini).unwrap())).unwrap(),
    )
    .unwrap();
    assert!(gemini["contents"][0]["parts"][0].get("fileData").is_none());
    assert_eq!(
        gemini["contents"][0]["parts"][0]["inlineData"]["mimeType"],
        "image/png"
    );
    let mut responses = input("r");
    responses["input"] = json!([{"role":"user","content":[{"type":"input_image","detail":"auto","file_id":"actual-file"}]}]);
    let responses = serde_json::to_value(
        ready(resources.responses(serde_json::from_value(responses).unwrap())).unwrap(),
    )
    .unwrap();
    assert!(
        responses["input"][0]["content"][0]["image_url"]
            .as_str()
            .unwrap()
            .starts_with("data:image/png;base64,")
    );
    assert!(responses["input"][0]["content"][0].get("file_id").is_none());
    assert_eq!(access.reads.lock().unwrap().len(), 3);
}

#[test]
fn resource_lengths_mime_and_aggregate_budgets_are_checked() {
    let mut access = Resources::png();
    access.length = Some(1);
    let scope = "source".into();
    let mut request = input("h");
    request["messages"] = json!([{"role":"user","content":[{"type":"image_url","image_url":{"url":"https://source/image"}}]}]);
    assert_eq!(
        ready(resources(&access, &scope).chat(serde_json::from_value(request.clone()).unwrap()))
            .unwrap_err()
            .kind(),
        TransformErrorKind::InvalidResult
    );
    access.length = Some(access.bytes.len() as u64);
    access.mime = "image/jpeg".into();
    assert!(
        ready(resources(&access, &scope).chat(serde_json::from_value(request.clone()).unwrap()))
            .is_err()
    );
    access.mime = "image/png".into();
    let part = request["messages"][0]["content"][0].clone();
    request["messages"][0]["content"] = json!([part.clone(), part]);
    let mut ctx = resources(&access, &scope);
    ctx.limits.max_body_bytes = access.bytes.len() as u64;
    assert_eq!(
        ready(ctx.chat(serde_json::from_value(request).unwrap()))
            .unwrap_err()
            .kind(),
        TransformErrorKind::Limit
    );
}