gproxy_protocol/transform/guardian/request/
claude.rs1use super::*;
2
3pub fn prepare_claude(
4 input: source::GuardianRequestBody,
5 context: GuardianRequestContext,
6) -> Result<Converted<GuardianPreparedRequest>, TransformError> {
7 prepare_claude_with_limits(input, context, default_history_limits())
8}
9
10pub fn prepare_claude_with_limits(
11 input: source::GuardianRequestBody,
12 context: GuardianRequestContext,
13 limits: CodecLimits,
14) -> Result<Converted<GuardianPreparedRequest>, TransformError> {
15 prepare_claude_plan(input, context, limits, true)
16}
17
18pub(super) fn prepare_claude_plan(
19 input: source::GuardianRequestBody,
20 context: GuardianRequestContext,
21 limits: CodecLimits,
22 attach: bool,
23) -> Result<Converted<GuardianPreparedRequest>, TransformError> {
24 let input = input.into_declared();
25
26 bound_source(&input, limits)?;
27 let payload = task_payload(&input, context.operation, limits)?;
28 let mut body = cg::GenerateContentRequestBody::builder(
29 context.max_tokens,
30 vec![cc::Message::builder(cc::Role::User, cc::MessageContent::Text(payload)).build()],
31 context.target_model.clone(),
32 )
33 .build();
34 body.system = Some(ct::SystemPrompt::Text(instructions(
35 &input,
36 context.operation,
37 )));
38 body.stream = Some(false);
39 body.service_tier = input
40 .service_tier
41 .as_deref()
42 .map(|value| {
43 Ok(match value {
44 "auto" => cg::ServiceTier::Auto,
45 "default" => cg::ServiceTier::StandardOnly,
46 _ => {
47 return Err(TransformError::unsupported(
48 "guardian.service_tier",
49 "Claude lacks requested service tier",
50 ));
51 }
52 })
53 })
54 .map(crate::transform::optional)
55 .transpose()?
56 .flatten();
57
58 match effort(&input) {
59 None => {}
60 Some("none") => {
61 body.thinking = Some(ct::ThinkingConfig::Disabled(
62 ct::ThinkingDisabled::builder().build(),
63 ))
64 }
65 Some(level @ ("low" | "medium" | "high" | "xhigh" | "max")) => {
66 let level = match level {
67 "low" => ct::Effort::Low,
68 "medium" => ct::Effort::Medium,
69 "high" => ct::Effort::High,
70 "xhigh" => ct::Effort::Xhigh,
71 "max" => ct::Effort::Max,
72 _ => {
73 return Err(TransformError::unsupported(
74 "guardian.reasoning.effort",
75 "Claude lacks requested effort",
76 ));
77 }
78 };
79 body.thinking = Some(ct::ThinkingConfig::Adaptive(
80 ct::ThinkingAdaptive::builder().build(),
81 ));
82 body.output_config = Some(ct::OutputConfig::builder().effort(level).build());
83 }
84 Some(_) => {}
85 }
86 if context.operation == GuardianOperation::Review {
87 let (_, output_schema, _) = review_schema(&input)?;
88 body.output_format = Some(
89 ct::JsonOutputFormat::builder(ct::JsonOutputFormatType::JsonSchema, output_schema)
90 .build(),
91 );
92 }
93 let mut target = GuardianDialectRequest::Claude(request("/v1/messages", body));
94 let media = media(&input)?;
95
96 if attach {
97 attach_media(&mut target, &media)?;
98 }
99 preflight_request(&target, limits, limits.max_body_bytes)?;
100 let report = report(&input, &target);
101 Ok(Converted {
102 value: GuardianPreparedRequest {
103 operation: context.operation,
104 request: target,
105 source: input,
106 },
107 report,
108 })
109}