Skip to main content

agent_client_protocol_schema/v2/
conversion.rs

1//! Explicit conversion helpers for experimenting with ACP v2 while SDKs still speak v1.
2//!
3//! The conversions below intentionally move values field-by-field and
4//! variant-by-variant instead of serializing through JSON so v2 shape changes
5//! have obvious edit points.
6
7use std::{
8    collections::{BTreeMap, HashMap},
9    fmt,
10    hash::{BuildHasher, Hash},
11    path::{Path, PathBuf},
12    sync::Arc,
13};
14
15use serde_json::value::RawValue;
16
17use crate::version::ProtocolVersion;
18
19/// Result type returned by protocol conversion helpers.
20pub type Result<T> = std::result::Result<T, ProtocolConversionError>;
21
22/// Error returned when converting between v1 and v2 protocol type namespaces fails.
23#[derive(Debug, Clone, PartialEq, Eq)]
24#[non_exhaustive]
25pub struct ProtocolConversionError {
26    message: String,
27}
28
29impl ProtocolConversionError {
30    /// Creates a conversion error with a human-readable message.
31    #[must_use]
32    pub fn new(message: impl Into<String>) -> Self {
33        Self {
34            message: message.into(),
35        }
36    }
37
38    /// Returns the human-readable conversion error message.
39    #[must_use]
40    pub fn message(&self) -> &str {
41        &self.message
42    }
43}
44
45impl fmt::Display for ProtocolConversionError {
46    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
47        formatter.write_str(&self.message)
48    }
49}
50
51impl std::error::Error for ProtocolConversionError {}
52
53fn unknown_v2_enum_variant(type_name: &str, value: &str) -> ProtocolConversionError {
54    ProtocolConversionError::new(format!(
55        "v2 {type_name} variant `{value}` cannot be represented in v1"
56    ))
57}
58
59fn removed_v1_enum_variant(type_name: &str, value: &str) -> ProtocolConversionError {
60    ProtocolConversionError::new(format!(
61        "v1 {type_name} variant `{value}` cannot be represented in v2"
62    ))
63}
64
65const LEGACY_V1_PLAN_ID: &str = "main";
66
67/// Converts a [`ProtocolConversionError`] into a v1 [`Error`](crate::v1::Error)
68/// so callers can use `?` to bubble conversion failures through APIs that
69/// already speak the v1 error type.
70///
71/// The conversion is mapped onto [`Error::internal_error`](crate::v1::Error::internal_error)
72/// because a failed cross-version conversion always indicates a protocol
73/// mismatch on this side of the wire rather than a client mistake.
74impl From<ProtocolConversionError> for crate::v1::Error {
75    fn from(error: ProtocolConversionError) -> Self {
76        crate::v1::Error::internal_error().data(error.message)
77    }
78}
79
80/// Mirror of the [v1 `From`](#impl-From%3CProtocolConversionError%3E-for-Error)
81/// impl for the v2 [`Error`](crate::v2::Error) type.
82impl From<ProtocolConversionError> for crate::v2::Error {
83    fn from(error: ProtocolConversionError) -> Self {
84        crate::v2::Error::internal_error().data(error.message)
85    }
86}
87
88/// Converts a value from the v2 draft type namespace into the matching v1 type.
89pub trait IntoV1 {
90    /// The corresponding v1 type.
91    type Output;
92
93    /// Converts this value into the corresponding v1 type.
94    ///
95    /// # Errors
96    ///
97    /// Returns [`ProtocolConversionError`] when a value cannot be represented in v1.
98    fn into_v1(self) -> Result<Self::Output>;
99}
100
101/// Converts a value from the v2 draft type namespace into one or more v1 values.
102///
103/// Use this trait for protocol values where a single v2 value may need to fan
104/// out into multiple v1 values. For example, a whole v2 message update contains
105/// an array of content blocks, while v1 represents those blocks as separate
106/// chunk updates.
107///
108/// This is intentionally not blanket-implemented for every [`IntoV1`] type.
109/// Keeping one-to-one and one-to-many conversions separate makes future v2
110/// fan-out cases explicit and avoids trait coherence conflicts when an
111/// existing one-to-one shape grows a v2-only variant that needs fan-out.
112pub trait IntoV1Many {
113    /// The corresponding v1 item type.
114    type Output;
115
116    /// Converts this value into one or more corresponding v1 items.
117    ///
118    /// # Errors
119    ///
120    /// Returns [`ProtocolConversionError`] when a value cannot be represented in v1.
121    fn into_v1_many(self) -> Result<Vec<Self::Output>>;
122}
123
124/// Converts a value from the v1 type namespace into the matching v2 draft type.
125pub trait IntoV2 {
126    /// The corresponding v2 draft type.
127    type Output;
128
129    /// Converts this value into the corresponding v2 draft type.
130    ///
131    /// # Errors
132    ///
133    /// Returns [`ProtocolConversionError`] when a value cannot be represented in v2.
134    fn into_v2(self) -> Result<Self::Output>;
135}
136
137/// Converts a v2 draft value into the corresponding v1 value type.
138///
139/// # Errors
140///
141/// Returns [`ProtocolConversionError`] when a value cannot be represented in v1.
142pub fn v2_to_v1<T>(value: T) -> Result<T::Output>
143where
144    T: IntoV1,
145{
146    value.into_v1()
147}
148
149/// Converts a v2 draft value into one or more corresponding v1 values.
150///
151/// One-to-many conversions are stateless. When a v2 update's semantics depend
152/// on previously delivered updates, this helper can only reject cases that are
153/// visible in the value being converted. For example, a content-bearing whole
154/// message update can be emitted as v1 chunks, but v1 cannot represent the
155/// replacement semantics if the v1 side has already received content for that
156/// `messageId`.
157///
158/// # Errors
159///
160/// Returns [`ProtocolConversionError`] when a value cannot be represented in v1.
161pub fn v2_to_v1_many<T>(value: T) -> Result<Vec<T::Output>>
162where
163    T: IntoV1Many,
164{
165    value.into_v1_many()
166}
167
168/// Converts a v1 value into the corresponding v2 draft value type.
169///
170/// # Errors
171///
172/// Returns [`ProtocolConversionError`] when a value cannot be represented in v2.
173pub fn v1_to_v2<T>(value: T) -> Result<T::Output>
174where
175    T: IntoV2,
176{
177    value.into_v2()
178}
179
180macro_rules! identity_conversion {
181    ($($ty:ty),* $(,)?) => {
182        $(
183            impl IntoV1 for $ty {
184                type Output = Self;
185
186                fn into_v1(self) -> Result<Self::Output> {
187                    Ok(self)
188                }
189            }
190
191            impl IntoV2 for $ty {
192                type Output = Self;
193
194                fn into_v2(self) -> Result<Self::Output> {
195                    Ok(self)
196                }
197            }
198        )*
199    };
200}
201
202identity_conversion!(
203    bool,
204    f32,
205    f64,
206    i16,
207    i32,
208    i64,
209    i8,
210    isize,
211    String,
212    u16,
213    u32,
214    u64,
215    u8,
216    usize,
217    &'static str,
218    Arc<RawValue>,
219    Arc<str>,
220    PathBuf,
221    ProtocolVersion,
222    super::RequestId,
223    serde_json::Map<String, serde_json::Value>,
224    serde_json::Value,
225);
226
227impl<T> IntoV1 for Option<T>
228where
229    T: IntoV1,
230{
231    type Output = Option<T::Output>;
232    fn into_v1(self) -> Result<Self::Output> {
233        self.map(IntoV1::into_v1).transpose()
234    }
235}
236
237impl<T> IntoV2 for Option<T>
238where
239    T: IntoV2,
240{
241    type Output = Option<T::Output>;
242    fn into_v2(self) -> Result<Self::Output> {
243        self.map(IntoV2::into_v2).transpose()
244    }
245}
246
247impl<T> IntoV1 for Vec<T>
248where
249    T: IntoV1,
250{
251    type Output = Vec<T::Output>;
252    fn into_v1(self) -> Result<Self::Output> {
253        self.into_iter().map(IntoV1::into_v1).collect()
254    }
255}
256
257fn into_v1_default_on_error<T>(value: T) -> T::Output
258where
259    T: IntoV1,
260    T::Output: Default,
261{
262    value.into_v1().unwrap_or_default()
263}
264
265fn into_v2_default_on_error<T>(value: T) -> T::Output
266where
267    T: IntoV2,
268    T::Output: Default,
269{
270    value.into_v2().unwrap_or_default()
271}
272
273fn into_v1_vec_skip_errors<T>(values: Vec<T>) -> Vec<T::Output>
274where
275    T: IntoV1,
276{
277    values
278        .into_iter()
279        .filter_map(|value| value.into_v1().ok())
280        .collect()
281}
282
283fn into_v2_vec_skip_errors<T>(values: Vec<T>) -> Vec<T::Output>
284where
285    T: IntoV2,
286{
287    values
288        .into_iter()
289        .filter_map(|value| value.into_v2().ok())
290        .collect()
291}
292
293fn option_vec_into_v1_skip_errors<T>(value: Option<Vec<T>>) -> Option<Vec<T::Output>>
294where
295    T: IntoV1,
296{
297    value.map(into_v1_vec_skip_errors)
298}
299
300fn option_vec_into_v2_skip_errors<T>(value: Option<Vec<T>>) -> Option<Vec<T::Output>>
301where
302    T: IntoV2,
303{
304    value.map(into_v2_vec_skip_errors)
305}
306
307fn option_vec_into_v2_default_skip_errors<T>(value: Option<Vec<T>>) -> Vec<T::Output>
308where
309    T: IntoV2,
310{
311    value.map(into_v2_vec_skip_errors).unwrap_or_default()
312}
313
314impl<T> IntoV2 for Vec<T>
315where
316    T: IntoV2,
317{
318    type Output = Vec<T::Output>;
319    fn into_v2(self) -> Result<Self::Output> {
320        self.into_iter().map(IntoV2::into_v2).collect()
321    }
322}
323
324impl<K, V> IntoV1 for BTreeMap<K, V>
325where
326    K: IntoV1,
327    K::Output: Ord,
328    V: IntoV1,
329{
330    type Output = BTreeMap<K::Output, V::Output>;
331    fn into_v1(self) -> Result<Self::Output> {
332        self.into_iter()
333            .map(|(key, value)| Ok((key.into_v1()?, value.into_v1()?)))
334            .collect()
335    }
336}
337
338impl<K, V> IntoV2 for BTreeMap<K, V>
339where
340    K: IntoV2,
341    K::Output: Ord,
342    V: IntoV2,
343{
344    type Output = BTreeMap<K::Output, V::Output>;
345    fn into_v2(self) -> Result<Self::Output> {
346        self.into_iter()
347            .map(|(key, value)| Ok((key.into_v2()?, value.into_v2()?)))
348            .collect()
349    }
350}
351
352impl<K, V, S> IntoV1 for HashMap<K, V, S>
353where
354    K: IntoV1,
355    K::Output: Eq + Hash,
356    V: IntoV1,
357    S: BuildHasher,
358{
359    type Output = HashMap<K::Output, V::Output>;
360    fn into_v1(self) -> Result<Self::Output> {
361        self.into_iter()
362            .map(|(key, value)| Ok((key.into_v1()?, value.into_v1()?)))
363            .collect()
364    }
365}
366
367impl<K, V, S> IntoV2 for HashMap<K, V, S>
368where
369    K: IntoV2,
370    K::Output: Eq + Hash,
371    V: IntoV2,
372    S: BuildHasher,
373{
374    type Output = HashMap<K::Output, V::Output>;
375    fn into_v2(self) -> Result<Self::Output> {
376        self.into_iter()
377            .map(|(key, value)| Ok((key.into_v2()?, value.into_v2()?)))
378            .collect()
379    }
380}
381
382impl<T> IntoV1 for crate::MaybeUndefined<T>
383where
384    T: IntoV1,
385{
386    type Output = crate::MaybeUndefined<T::Output>;
387    fn into_v1(self) -> Result<Self::Output> {
388        Ok(match self {
389            Self::Undefined => crate::MaybeUndefined::Undefined,
390            Self::Null => crate::MaybeUndefined::Null,
391            Self::Value(value) => crate::MaybeUndefined::Value(value.into_v1()?),
392        })
393    }
394}
395
396impl<T> IntoV2 for crate::MaybeUndefined<T>
397where
398    T: IntoV2,
399{
400    type Output = crate::MaybeUndefined<T::Output>;
401    fn into_v2(self) -> Result<Self::Output> {
402        Ok(match self {
403            Self::Undefined => crate::MaybeUndefined::Undefined,
404            Self::Null => crate::MaybeUndefined::Null,
405            Self::Value(value) => crate::MaybeUndefined::Value(value.into_v2()?),
406        })
407    }
408}
409
410impl<Params> IntoV1 for super::Request<Params>
411where
412    Params: IntoV1,
413{
414    type Output = crate::v1::Request<Params::Output>;
415    fn into_v1(self) -> Result<Self::Output> {
416        Ok(crate::v1::Request {
417            id: self.id.into_v1()?,
418            method: self.method,
419            params: self.params.into_v1()?,
420        })
421    }
422}
423
424impl<Params> IntoV2 for crate::v1::Request<Params>
425where
426    Params: IntoV2,
427{
428    type Output = super::Request<Params::Output>;
429    fn into_v2(self) -> Result<Self::Output> {
430        Ok(super::Request {
431            id: self.id.into_v2()?,
432            method: self.method,
433            params: self.params.into_v2()?,
434        })
435    }
436}
437
438impl<Params> IntoV1 for super::Notification<Params>
439where
440    Params: IntoV1,
441{
442    type Output = crate::v1::Notification<Params::Output>;
443    fn into_v1(self) -> Result<Self::Output> {
444        Ok(crate::v1::Notification {
445            method: self.method,
446            params: self.params.into_v1()?,
447        })
448    }
449}
450
451impl<Params> IntoV2 for crate::v1::Notification<Params>
452where
453    Params: IntoV2,
454{
455    type Output = super::Notification<Params::Output>;
456    fn into_v2(self) -> Result<Self::Output> {
457        Ok(super::Notification {
458            method: self.method,
459            params: self.params.into_v2()?,
460        })
461    }
462}
463
464impl<Response> IntoV1 for super::Response<Response>
465where
466    Response: IntoV1,
467{
468    type Output = crate::v1::Response<Response::Output>;
469    fn into_v1(self) -> Result<Self::Output> {
470        Ok(match self {
471            Self::Result { id, result } => crate::v1::Response::Result {
472                id: id.into_v1()?,
473                result: result.into_v1()?,
474            },
475            Self::Error { id, error } => crate::v1::Response::Error {
476                id: id.into_v1()?,
477                error: error.into_v1()?,
478            },
479        })
480    }
481}
482
483impl<Response> IntoV2 for crate::v1::Response<Response>
484where
485    Response: IntoV2,
486{
487    type Output = super::Response<Response::Output>;
488    fn into_v2(self) -> Result<Self::Output> {
489        Ok(match self {
490            Self::Result { id, result } => super::Response::Result {
491                id: id.into_v2()?,
492                result: result.into_v2()?,
493            },
494            Self::Error { id, error } => super::Response::Error {
495                id: id.into_v2()?,
496                error: error.into_v2()?,
497            },
498        })
499    }
500}
501
502impl<Message> IntoV1 for super::JsonRpcMessage<Message>
503where
504    Message: IntoV1,
505{
506    type Output = crate::v1::JsonRpcMessage<Message::Output>;
507    fn into_v1(self) -> Result<Self::Output> {
508        Ok(crate::v1::JsonRpcMessage::wrap(
509            self.into_inner().into_v1()?,
510        ))
511    }
512}
513
514impl<Message> IntoV2 for crate::v1::JsonRpcMessage<Message>
515where
516    Message: IntoV2,
517{
518    type Output = super::JsonRpcMessage<Message::Output>;
519    fn into_v2(self) -> Result<Self::Output> {
520        Ok(super::JsonRpcMessage::wrap(self.into_inner().into_v2()?))
521    }
522}
523
524impl IntoV1Many for super::Notification<super::AgentNotification> {
525    type Output = crate::v1::Notification<crate::v1::AgentNotification>;
526
527    fn into_v1_many(self) -> Result<Vec<Self::Output>> {
528        let Self { method, params } = self;
529        let Some(params) = params else {
530            return Ok(vec![crate::v1::Notification {
531                method,
532                params: None,
533            }]);
534        };
535
536        params
537            .into_v1_many()?
538            .into_iter()
539            .map(|params| {
540                Ok(crate::v1::Notification {
541                    method: method.clone(),
542                    params: Some(params),
543                })
544            })
545            .collect()
546    }
547}
548
549impl IntoV1Many for super::JsonRpcMessage<super::Notification<super::AgentNotification>> {
550    type Output = crate::v1::JsonRpcMessage<crate::v1::Notification<crate::v1::AgentNotification>>;
551
552    fn into_v1_many(self) -> Result<Vec<Self::Output>> {
553        self.into_inner()
554            .into_v1_many()?
555            .into_iter()
556            .map(|message| Ok(crate::v1::JsonRpcMessage::wrap(message)))
557            .collect()
558    }
559}
560
561impl IntoV1Many for super::JsonRpcBatch<super::Notification<super::AgentNotification>> {
562    type Output = crate::v1::JsonRpcMessage<crate::v1::Notification<crate::v1::AgentNotification>>;
563
564    fn into_v1_many(self) -> Result<Vec<Self::Output>> {
565        let messages = self
566            .into_vec()
567            .into_iter()
568            .map(IntoV1Many::into_v1_many)
569            .collect::<Result<Vec<_>>>()?
570            .into_iter()
571            .flatten()
572            .collect();
573        Ok(messages)
574    }
575}
576
577impl IntoV1 for super::SessionId {
578    type Output = crate::v1::SessionId;
579
580    fn into_v1(self) -> Result<Self::Output> {
581        Ok(crate::v1::SessionId(self.0.into_v1()?))
582    }
583}
584
585impl IntoV2 for crate::v1::SessionId {
586    type Output = super::SessionId;
587
588    fn into_v2(self) -> Result<Self::Output> {
589        Ok(super::SessionId(self.0.into_v2()?))
590    }
591}
592
593impl IntoV1 for super::MessageId {
594    type Output = crate::v1::MessageId;
595
596    fn into_v1(self) -> Result<Self::Output> {
597        Ok(crate::v1::MessageId(self.0.into_v1()?))
598    }
599}
600
601impl IntoV2 for crate::v1::MessageId {
602    type Output = super::MessageId;
603
604    fn into_v2(self) -> Result<Self::Output> {
605        Ok(super::MessageId(self.0.into_v2()?))
606    }
607}
608
609#[cfg(not(feature = "unstable_plan_operations"))]
610impl IntoV1 for super::PlanUpdate {
611    type Output = crate::v1::Plan;
612
613    fn into_v1(self) -> Result<Self::Output> {
614        let Self { plan, meta } = self;
615        Ok(match plan {
616            super::PlanUpdateContent::Items(items) => {
617                let super::PlanItems {
618                    plan_id: _,
619                    entries,
620                    meta: items_meta,
621                } = items;
622                crate::v1::Plan {
623                    entries: into_v1_vec_skip_errors(entries),
624                    meta: meta.or(items_meta).into_v1()?,
625                }
626            }
627            super::PlanUpdateContent::Other(value) => {
628                return Err(unknown_v2_enum_variant("PlanUpdateContent", &value.type_));
629            }
630        })
631    }
632}
633
634#[cfg(feature = "unstable_plan_operations")]
635impl IntoV1 for super::PlanId {
636    type Output = crate::v1::PlanId;
637
638    fn into_v1(self) -> Result<Self::Output> {
639        Ok(crate::v1::PlanId(self.0.into_v1()?))
640    }
641}
642
643#[cfg(feature = "unstable_plan_operations")]
644impl IntoV2 for crate::v1::PlanId {
645    type Output = super::PlanId;
646
647    fn into_v2(self) -> Result<Self::Output> {
648        Ok(super::PlanId(self.0.into_v2()?))
649    }
650}
651
652#[cfg(feature = "unstable_plan_operations")]
653impl IntoV1 for super::PlanUpdate {
654    type Output = crate::v1::PlanUpdate;
655
656    fn into_v1(self) -> Result<Self::Output> {
657        let Self { plan, meta } = self;
658        Ok(crate::v1::PlanUpdate {
659            plan: plan.into_v1()?,
660            meta: meta.into_v1()?,
661        })
662    }
663}
664
665#[cfg(feature = "unstable_plan_operations")]
666impl IntoV2 for crate::v1::PlanUpdate {
667    type Output = super::PlanUpdate;
668
669    fn into_v2(self) -> Result<Self::Output> {
670        let Self { plan, meta } = self;
671        Ok(super::PlanUpdate {
672            plan: plan.into_v2()?,
673            meta: meta.into_v2()?,
674        })
675    }
676}
677
678#[cfg(feature = "unstable_plan_operations")]
679impl IntoV1 for super::PlanUpdateContent {
680    type Output = crate::v1::PlanUpdateContent;
681
682    fn into_v1(self) -> Result<Self::Output> {
683        Ok(match self {
684            Self::Items(value) => crate::v1::PlanUpdateContent::Items(value.into_v1()?),
685            Self::File(value) => crate::v1::PlanUpdateContent::File(value.into_v1()?),
686            Self::Markdown(value) => crate::v1::PlanUpdateContent::Markdown(value.into_v1()?),
687            Self::Other(value) => {
688                return Err(unknown_v2_enum_variant("PlanUpdateContent", &value.type_));
689            }
690        })
691    }
692}
693
694#[cfg(feature = "unstable_plan_operations")]
695impl IntoV2 for crate::v1::PlanUpdateContent {
696    type Output = super::PlanUpdateContent;
697
698    fn into_v2(self) -> Result<Self::Output> {
699        Ok(match self {
700            Self::Items(value) => super::PlanUpdateContent::Items(value.into_v2()?),
701            Self::File(value) => super::PlanUpdateContent::File(value.into_v2()?),
702            Self::Markdown(value) => super::PlanUpdateContent::Markdown(value.into_v2()?),
703        })
704    }
705}
706
707#[cfg(feature = "unstable_plan_operations")]
708impl IntoV1 for super::PlanItems {
709    type Output = crate::v1::PlanItems;
710
711    fn into_v1(self) -> Result<Self::Output> {
712        let Self {
713            plan_id,
714            entries,
715            meta,
716        } = self;
717        Ok(crate::v1::PlanItems {
718            plan_id: plan_id.into_v1()?,
719            entries: into_v1_vec_skip_errors(entries),
720            meta: meta.into_v1()?,
721        })
722    }
723}
724
725#[cfg(feature = "unstable_plan_operations")]
726impl IntoV2 for crate::v1::PlanItems {
727    type Output = super::PlanItems;
728
729    fn into_v2(self) -> Result<Self::Output> {
730        let Self {
731            plan_id,
732            entries,
733            meta,
734        } = self;
735        Ok(super::PlanItems {
736            plan_id: plan_id.into_v2()?,
737            entries: into_v2_vec_skip_errors(entries),
738            meta: meta.into_v2()?,
739        })
740    }
741}
742
743#[cfg(feature = "unstable_plan_operations")]
744impl IntoV1 for super::PlanFile {
745    type Output = crate::v1::PlanFile;
746
747    fn into_v1(self) -> Result<Self::Output> {
748        let Self { plan_id, uri, meta } = self;
749        Ok(crate::v1::PlanFile {
750            plan_id: plan_id.into_v1()?,
751            uri: uri.into_v1()?,
752            meta: meta.into_v1()?,
753        })
754    }
755}
756
757#[cfg(feature = "unstable_plan_operations")]
758impl IntoV2 for crate::v1::PlanFile {
759    type Output = super::PlanFile;
760
761    fn into_v2(self) -> Result<Self::Output> {
762        let Self { plan_id, uri, meta } = self;
763        Ok(super::PlanFile {
764            plan_id: plan_id.into_v2()?,
765            uri: uri.into_v2()?,
766            meta: meta.into_v2()?,
767        })
768    }
769}
770
771#[cfg(feature = "unstable_plan_operations")]
772impl IntoV1 for super::PlanMarkdown {
773    type Output = crate::v1::PlanMarkdown;
774
775    fn into_v1(self) -> Result<Self::Output> {
776        let Self {
777            plan_id,
778            content,
779            meta,
780        } = self;
781        Ok(crate::v1::PlanMarkdown {
782            plan_id: plan_id.into_v1()?,
783            content: content.into_v1()?,
784            meta: meta.into_v1()?,
785        })
786    }
787}
788
789#[cfg(feature = "unstable_plan_operations")]
790impl IntoV2 for crate::v1::PlanMarkdown {
791    type Output = super::PlanMarkdown;
792
793    fn into_v2(self) -> Result<Self::Output> {
794        let Self {
795            plan_id,
796            content,
797            meta,
798        } = self;
799        Ok(super::PlanMarkdown {
800            plan_id: plan_id.into_v2()?,
801            content: content.into_v2()?,
802            meta: meta.into_v2()?,
803        })
804    }
805}
806
807#[cfg(feature = "unstable_plan_operations")]
808impl IntoV1 for super::PlanRemoved {
809    type Output = crate::v1::PlanRemoved;
810
811    fn into_v1(self) -> Result<Self::Output> {
812        let Self { plan_id, meta } = self;
813        Ok(crate::v1::PlanRemoved {
814            plan_id: plan_id.into_v1()?,
815            meta: meta.into_v1()?,
816        })
817    }
818}
819
820#[cfg(feature = "unstable_plan_operations")]
821impl IntoV2 for crate::v1::PlanRemoved {
822    type Output = super::PlanRemoved;
823
824    fn into_v2(self) -> Result<Self::Output> {
825        let Self { plan_id, meta } = self;
826        Ok(super::PlanRemoved {
827            plan_id: plan_id.into_v2()?,
828            meta: meta.into_v2()?,
829        })
830    }
831}
832
833impl IntoV1 for super::PlanEntry {
834    type Output = crate::v1::PlanEntry;
835
836    fn into_v1(self) -> Result<Self::Output> {
837        let Self {
838            content,
839            priority,
840            status,
841            meta,
842        } = self;
843        Ok(crate::v1::PlanEntry {
844            content: content.into_v1()?,
845            priority: priority.into_v1()?,
846            status: status.into_v1()?,
847            meta: meta.into_v1()?,
848        })
849    }
850}
851
852impl IntoV2 for crate::v1::PlanEntry {
853    type Output = super::PlanEntry;
854
855    fn into_v2(self) -> Result<Self::Output> {
856        let Self {
857            content,
858            priority,
859            status,
860            meta,
861        } = self;
862        Ok(super::PlanEntry {
863            content: content.into_v2()?,
864            priority: priority.into_v2()?,
865            status: status.into_v2()?,
866            meta: meta.into_v2()?,
867        })
868    }
869}
870
871impl IntoV1 for super::PlanEntryPriority {
872    type Output = crate::v1::PlanEntryPriority;
873
874    fn into_v1(self) -> Result<Self::Output> {
875        Ok(match self {
876            Self::High => crate::v1::PlanEntryPriority::High,
877            Self::Medium => crate::v1::PlanEntryPriority::Medium,
878            Self::Low => crate::v1::PlanEntryPriority::Low,
879            Self::Other(value) => {
880                return Err(unknown_v2_enum_variant("PlanEntryPriority", &value));
881            }
882        })
883    }
884}
885
886impl IntoV2 for crate::v1::PlanEntryPriority {
887    type Output = super::PlanEntryPriority;
888
889    fn into_v2(self) -> Result<Self::Output> {
890        Ok(match self {
891            Self::High => super::PlanEntryPriority::High,
892            Self::Medium => super::PlanEntryPriority::Medium,
893            Self::Low => super::PlanEntryPriority::Low,
894        })
895    }
896}
897
898impl IntoV1 for super::PlanEntryStatus {
899    type Output = crate::v1::PlanEntryStatus;
900
901    fn into_v1(self) -> Result<Self::Output> {
902        Ok(match self {
903            Self::Pending => crate::v1::PlanEntryStatus::Pending,
904            Self::InProgress => crate::v1::PlanEntryStatus::InProgress,
905            Self::Completed => crate::v1::PlanEntryStatus::Completed,
906            Self::Other(value) => return Err(unknown_v2_enum_variant("PlanEntryStatus", &value)),
907        })
908    }
909}
910
911impl IntoV2 for crate::v1::PlanEntryStatus {
912    type Output = super::PlanEntryStatus;
913
914    fn into_v2(self) -> Result<Self::Output> {
915        Ok(match self {
916            Self::Pending => super::PlanEntryStatus::Pending,
917            Self::InProgress => super::PlanEntryStatus::InProgress,
918            Self::Completed => super::PlanEntryStatus::Completed,
919        })
920    }
921}
922
923impl IntoV1 for super::CancelRequestNotification {
924    type Output = crate::v1::CancelRequestNotification;
925
926    fn into_v1(self) -> Result<Self::Output> {
927        let Self { request_id, meta } = self;
928        Ok(crate::v1::CancelRequestNotification {
929            request_id: request_id.into_v1()?,
930            meta: meta.into_v1()?,
931        })
932    }
933}
934
935impl IntoV2 for crate::v1::CancelRequestNotification {
936    type Output = super::CancelRequestNotification;
937
938    fn into_v2(self) -> Result<Self::Output> {
939        let Self { request_id, meta } = self;
940        Ok(super::CancelRequestNotification {
941            request_id: request_id.into_v2()?,
942            meta: meta.into_v2()?,
943        })
944    }
945}
946
947impl IntoV1 for super::ProtocolLevelNotification {
948    type Output = crate::v1::ProtocolLevelNotification;
949
950    fn into_v1(self) -> Result<Self::Output> {
951        Ok(match self {
952            Self::CancelRequestNotification(value) => {
953                crate::v1::ProtocolLevelNotification::CancelRequestNotification(value.into_v1()?)
954            }
955        })
956    }
957}
958
959impl IntoV2 for crate::v1::ProtocolLevelNotification {
960    type Output = super::ProtocolLevelNotification;
961
962    fn into_v2(self) -> Result<Self::Output> {
963        Ok(match self {
964            Self::CancelRequestNotification(value) => {
965                super::ProtocolLevelNotification::CancelRequestNotification(value.into_v2()?)
966            }
967        })
968    }
969}
970
971impl IntoV1Many for super::UpdateSessionNotification {
972    type Output = crate::v1::SessionNotification;
973
974    fn into_v1_many(self) -> Result<Vec<Self::Output>> {
975        let Self {
976            session_id,
977            update,
978            meta,
979        } = self;
980        let session_id = session_id.into_v1()?;
981        let meta = meta.into_v1()?;
982        update
983            .into_v1_many()?
984            .into_iter()
985            .map(|update| {
986                Ok(crate::v1::SessionNotification {
987                    session_id: session_id.clone(),
988                    update,
989                    meta: meta.clone(),
990                })
991            })
992            .collect()
993    }
994}
995
996impl IntoV2 for crate::v1::SessionNotification {
997    type Output = super::UpdateSessionNotification;
998
999    fn into_v2(self) -> Result<Self::Output> {
1000        let Self {
1001            session_id,
1002            update,
1003            meta,
1004        } = self;
1005        Ok(super::UpdateSessionNotification {
1006            session_id: session_id.into_v2()?,
1007            update: update.into_v2()?,
1008            meta: meta.into_v2()?,
1009        })
1010    }
1011}
1012
1013impl IntoV1Many for super::SessionUpdate {
1014    type Output = crate::v1::SessionUpdate;
1015
1016    fn into_v1_many(self) -> Result<Vec<Self::Output>> {
1017        Ok(match self {
1018            Self::UserMessageChunk(value) => {
1019                vec![crate::v1::SessionUpdate::UserMessageChunk(value.into_v1()?)]
1020            }
1021            Self::UserMessage(value) => v2_message_update_into_v1_chunks(
1022                "user_message",
1023                value.message_id,
1024                value.content,
1025                value.meta,
1026                crate::v1::SessionUpdate::UserMessageChunk,
1027            )?,
1028            Self::AgentMessageChunk(value) => {
1029                vec![crate::v1::SessionUpdate::AgentMessageChunk(
1030                    value.into_v1()?,
1031                )]
1032            }
1033            Self::AgentMessage(value) => v2_message_update_into_v1_chunks(
1034                "agent_message",
1035                value.message_id,
1036                value.content,
1037                value.meta,
1038                crate::v1::SessionUpdate::AgentMessageChunk,
1039            )?,
1040            Self::AgentThoughtChunk(value) => {
1041                vec![crate::v1::SessionUpdate::AgentThoughtChunk(
1042                    value.into_v1()?,
1043                )]
1044            }
1045            Self::AgentThought(value) => v2_message_update_into_v1_chunks(
1046                "agent_thought",
1047                value.message_id,
1048                value.content,
1049                value.meta,
1050                crate::v1::SessionUpdate::AgentThoughtChunk,
1051            )?,
1052            Self::StateUpdate(_) => {
1053                return Err(ProtocolConversionError::new(
1054                    "v2 SessionUpdate variant `state_update` cannot be represented in v1 because v1 reports completion in the session/prompt response",
1055                ));
1056            }
1057            Self::ToolCallContentChunk(_) => {
1058                return Err(ProtocolConversionError::new(
1059                    "v2 SessionUpdate variant `tool_call_content_chunk` cannot be represented in v1 because v1 tool-call content updates replace content instead of appending",
1060                ));
1061            }
1062            Self::ToolCallUpdate(value) => {
1063                vec![crate::v1::SessionUpdate::ToolCallUpdate(value.into_v1()?)]
1064            }
1065            #[cfg(feature = "unstable_plan_operations")]
1066            Self::PlanUpdate(value) => vec![crate::v1::SessionUpdate::PlanUpdate(value.into_v1()?)],
1067            #[cfg(not(feature = "unstable_plan_operations"))]
1068            Self::PlanUpdate(value) => vec![crate::v1::SessionUpdate::Plan(value.into_v1()?)],
1069            #[cfg(feature = "unstable_plan_operations")]
1070            Self::PlanRemoved(value) => {
1071                vec![crate::v1::SessionUpdate::PlanRemoved(value.into_v1()?)]
1072            }
1073            Self::AvailableCommandsUpdate(value) => {
1074                vec![crate::v1::SessionUpdate::AvailableCommandsUpdate(
1075                    value.into_v1()?,
1076                )]
1077            }
1078            Self::ConfigOptionUpdate(value) => {
1079                vec![crate::v1::SessionUpdate::ConfigOptionUpdate(
1080                    value.into_v1()?,
1081                )]
1082            }
1083            Self::SessionInfoUpdate(value) => {
1084                vec![crate::v1::SessionUpdate::SessionInfoUpdate(
1085                    value.into_v1()?,
1086                )]
1087            }
1088            Self::UsageUpdate(value) => {
1089                vec![crate::v1::SessionUpdate::UsageUpdate(value.into_v1()?)]
1090            }
1091            Self::Other(value) => {
1092                return Err(unknown_v2_enum_variant(
1093                    "SessionUpdate",
1094                    &value.session_update,
1095                ));
1096            }
1097        })
1098    }
1099}
1100
1101fn v2_message_update_into_v1_chunks(
1102    variant: &str,
1103    message_id: super::MessageId,
1104    content: crate::MaybeUndefined<Vec<super::ContentBlock>>,
1105    meta: crate::MaybeUndefined<super::Meta>,
1106    wrap: impl Fn(crate::v1::ContentChunk) -> crate::v1::SessionUpdate,
1107) -> Result<Vec<crate::v1::SessionUpdate>> {
1108    let content = match content {
1109        crate::MaybeUndefined::Value(content) if !content.is_empty() => content,
1110        crate::MaybeUndefined::Value(_) => {
1111            return Err(ProtocolConversionError::new(format!(
1112                "v2 SessionUpdate variant `{variant}` with empty content cannot be represented in v1 chunks"
1113            )));
1114        }
1115        crate::MaybeUndefined::Null => {
1116            return Err(ProtocolConversionError::new(format!(
1117                "v2 SessionUpdate variant `{variant}` with null content cannot be represented in v1 chunks"
1118            )));
1119        }
1120        crate::MaybeUndefined::Undefined => {
1121            return Err(ProtocolConversionError::new(format!(
1122                "v2 SessionUpdate variant `{variant}` without content cannot be represented in v1 chunks"
1123            )));
1124        }
1125    };
1126    let message_id = message_id.into_v1()?;
1127    let meta = match meta {
1128        crate::MaybeUndefined::Value(meta) => Some(meta.into_v1()?),
1129        crate::MaybeUndefined::Null => {
1130            return Err(ProtocolConversionError::new(format!(
1131                "v2 SessionUpdate variant `{variant}` with null _meta cannot be represented in v1 chunks"
1132            )));
1133        }
1134        crate::MaybeUndefined::Undefined => None,
1135    };
1136
1137    content
1138        .into_iter()
1139        .map(|content| {
1140            Ok(wrap(crate::v1::ContentChunk {
1141                content: content.into_v1()?,
1142                message_id: Some(message_id.clone()),
1143                meta: meta.clone(),
1144            }))
1145        })
1146        .collect()
1147}
1148
1149impl IntoV2 for crate::v1::SessionUpdate {
1150    type Output = super::SessionUpdate;
1151
1152    fn into_v2(self) -> Result<Self::Output> {
1153        Ok(match self {
1154            Self::UserMessageChunk(value) => {
1155                super::SessionUpdate::UserMessageChunk(value.into_v2()?)
1156            }
1157            Self::AgentMessageChunk(value) => {
1158                super::SessionUpdate::AgentMessageChunk(value.into_v2()?)
1159            }
1160            Self::AgentThoughtChunk(value) => {
1161                super::SessionUpdate::AgentThoughtChunk(value.into_v2()?)
1162            }
1163            Self::ToolCall(value) => super::SessionUpdate::ToolCallUpdate(value.into_v2()?),
1164            Self::ToolCallUpdate(value) => super::SessionUpdate::ToolCallUpdate(value.into_v2()?),
1165            Self::Plan(value) => {
1166                let crate::v1::Plan { entries, meta } = value;
1167                super::SessionUpdate::PlanUpdate(super::PlanUpdate {
1168                    plan: super::PlanUpdateContent::items(LEGACY_V1_PLAN_ID, entries.into_v2()?),
1169                    meta: meta.into_v2()?,
1170                })
1171            }
1172            #[cfg(feature = "unstable_plan_operations")]
1173            Self::PlanUpdate(value) => super::SessionUpdate::PlanUpdate(value.into_v2()?),
1174            #[cfg(feature = "unstable_plan_operations")]
1175            Self::PlanRemoved(value) => super::SessionUpdate::PlanRemoved(value.into_v2()?),
1176            Self::AvailableCommandsUpdate(value) => {
1177                super::SessionUpdate::AvailableCommandsUpdate(value.into_v2()?)
1178            }
1179            Self::CurrentModeUpdate(_) => {
1180                return Err(removed_v1_enum_variant(
1181                    "SessionUpdate",
1182                    "current_mode_update",
1183                ));
1184            }
1185            Self::ConfigOptionUpdate(value) => {
1186                super::SessionUpdate::ConfigOptionUpdate(value.into_v2()?)
1187            }
1188            Self::SessionInfoUpdate(value) => {
1189                super::SessionUpdate::SessionInfoUpdate(value.into_v2()?)
1190            }
1191            Self::UsageUpdate(value) => super::SessionUpdate::UsageUpdate(value.into_v2()?),
1192        })
1193    }
1194}
1195
1196impl IntoV1 for super::ConfigOptionUpdate {
1197    type Output = crate::v1::ConfigOptionUpdate;
1198
1199    fn into_v1(self) -> Result<Self::Output> {
1200        let Self {
1201            config_options,
1202            meta,
1203        } = self;
1204        Ok(crate::v1::ConfigOptionUpdate {
1205            config_options: into_v1_vec_skip_errors(config_options),
1206            meta: meta.into_v1()?,
1207        })
1208    }
1209}
1210
1211impl IntoV2 for crate::v1::ConfigOptionUpdate {
1212    type Output = super::ConfigOptionUpdate;
1213
1214    fn into_v2(self) -> Result<Self::Output> {
1215        let Self {
1216            config_options,
1217            meta,
1218        } = self;
1219        Ok(super::ConfigOptionUpdate {
1220            config_options: into_v2_vec_skip_errors(config_options),
1221            meta: meta.into_v2()?,
1222        })
1223    }
1224}
1225
1226impl IntoV1 for super::SessionInfoUpdate {
1227    type Output = crate::v1::SessionInfoUpdate;
1228
1229    fn into_v1(self) -> Result<Self::Output> {
1230        let Self {
1231            title,
1232            updated_at,
1233            meta,
1234        } = self;
1235        Ok(crate::v1::SessionInfoUpdate {
1236            title: title.into_v1()?,
1237            updated_at: updated_at.into_v1()?,
1238            meta: maybe_undefined_meta_into_v1_option("SessionInfoUpdate", meta)?,
1239        })
1240    }
1241}
1242
1243impl IntoV2 for crate::v1::SessionInfoUpdate {
1244    type Output = super::SessionInfoUpdate;
1245
1246    fn into_v2(self) -> Result<Self::Output> {
1247        let Self {
1248            title,
1249            updated_at,
1250            meta,
1251        } = self;
1252        Ok(super::SessionInfoUpdate {
1253            title: title.into_v2()?,
1254            updated_at: updated_at.into_v2()?,
1255            meta: option_into_v2_maybe_undefined(meta)?,
1256        })
1257    }
1258}
1259
1260impl IntoV1 for super::UsageUpdate {
1261    type Output = crate::v1::UsageUpdate;
1262
1263    fn into_v1(self) -> Result<Self::Output> {
1264        let Self {
1265            used,
1266            size,
1267            cost,
1268            meta,
1269        } = self;
1270        Ok(crate::v1::UsageUpdate {
1271            used: used.into_v1()?,
1272            size: size.into_v1()?,
1273            cost: into_v1_default_on_error(cost),
1274            meta: meta.into_v1()?,
1275        })
1276    }
1277}
1278
1279impl IntoV2 for crate::v1::UsageUpdate {
1280    type Output = super::UsageUpdate;
1281
1282    fn into_v2(self) -> Result<Self::Output> {
1283        let Self {
1284            used,
1285            size,
1286            cost,
1287            meta,
1288        } = self;
1289        Ok(super::UsageUpdate {
1290            used: used.into_v2()?,
1291            size: size.into_v2()?,
1292            cost: into_v2_default_on_error(cost),
1293            meta: meta.into_v2()?,
1294        })
1295    }
1296}
1297
1298impl IntoV1 for super::Cost {
1299    type Output = crate::v1::Cost;
1300
1301    fn into_v1(self) -> Result<Self::Output> {
1302        let Self {
1303            amount,
1304            currency,
1305            meta,
1306        } = self;
1307        Ok(crate::v1::Cost {
1308            amount: amount.into_v1()?,
1309            currency: currency.into_v1()?,
1310            meta: meta.into_v1()?,
1311        })
1312    }
1313}
1314
1315impl IntoV2 for crate::v1::Cost {
1316    type Output = super::Cost;
1317
1318    fn into_v2(self) -> Result<Self::Output> {
1319        let Self {
1320            amount,
1321            currency,
1322            meta,
1323        } = self;
1324        Ok(super::Cost {
1325            amount: amount.into_v2()?,
1326            currency: currency.into_v2()?,
1327            meta: meta.into_v2()?,
1328        })
1329    }
1330}
1331
1332impl IntoV1 for super::ContentChunk {
1333    type Output = crate::v1::ContentChunk;
1334
1335    fn into_v1(self) -> Result<Self::Output> {
1336        let Self {
1337            content,
1338            message_id,
1339            meta,
1340        } = self;
1341        Ok(crate::v1::ContentChunk {
1342            content: content.into_v1()?,
1343            message_id: Some(message_id.into_v1()?),
1344            meta: meta.into_v1()?,
1345        })
1346    }
1347}
1348
1349impl IntoV2 for crate::v1::ContentChunk {
1350    type Output = super::ContentChunk;
1351
1352    fn into_v2(self) -> Result<Self::Output> {
1353        let Self {
1354            content,
1355            message_id,
1356            meta,
1357        } = self;
1358        Ok(super::ContentChunk {
1359            content: content.into_v2()?,
1360            message_id: message_id
1361                .ok_or_else(|| {
1362                    ProtocolConversionError::new(
1363                        "v1 ContentChunk without messageId cannot be represented in v2",
1364                    )
1365                })?
1366                .into_v2()?,
1367            meta: meta.into_v2()?,
1368        })
1369    }
1370}
1371
1372impl IntoV1 for super::AvailableCommandsUpdate {
1373    type Output = crate::v1::AvailableCommandsUpdate;
1374
1375    fn into_v1(self) -> Result<Self::Output> {
1376        let Self {
1377            available_commands,
1378            meta,
1379        } = self;
1380        Ok(crate::v1::AvailableCommandsUpdate {
1381            available_commands: into_v1_vec_skip_errors(available_commands),
1382            meta: meta.into_v1()?,
1383        })
1384    }
1385}
1386
1387impl IntoV2 for crate::v1::AvailableCommandsUpdate {
1388    type Output = super::AvailableCommandsUpdate;
1389
1390    fn into_v2(self) -> Result<Self::Output> {
1391        let Self {
1392            available_commands,
1393            meta,
1394        } = self;
1395        Ok(super::AvailableCommandsUpdate {
1396            available_commands: into_v2_vec_skip_errors(available_commands),
1397            meta: meta.into_v2()?,
1398        })
1399    }
1400}
1401
1402impl IntoV1 for super::AvailableCommand {
1403    type Output = crate::v1::AvailableCommand;
1404
1405    fn into_v1(self) -> Result<Self::Output> {
1406        let Self {
1407            name,
1408            description,
1409            input,
1410            meta,
1411        } = self;
1412        Ok(crate::v1::AvailableCommand {
1413            name: name.into_v1()?,
1414            description: description.into_v1()?,
1415            input: into_v1_default_on_error(input),
1416            meta: meta.into_v1()?,
1417        })
1418    }
1419}
1420
1421impl IntoV2 for crate::v1::AvailableCommand {
1422    type Output = super::AvailableCommand;
1423
1424    fn into_v2(self) -> Result<Self::Output> {
1425        let Self {
1426            name,
1427            description,
1428            input,
1429            meta,
1430        } = self;
1431        Ok(super::AvailableCommand {
1432            name: name.into_v2()?,
1433            description: description.into_v2()?,
1434            input: into_v2_default_on_error(input),
1435            meta: meta.into_v2()?,
1436        })
1437    }
1438}
1439
1440impl IntoV1 for super::AvailableCommandInput {
1441    type Output = crate::v1::AvailableCommandInput;
1442
1443    fn into_v1(self) -> Result<Self::Output> {
1444        Ok(match self {
1445            Self::Text(value) => crate::v1::AvailableCommandInput::Unstructured(value.into_v1()?),
1446            Self::Other(value) => {
1447                return Err(unknown_v2_enum_variant(
1448                    "AvailableCommandInput",
1449                    &value.type_,
1450                ));
1451            }
1452        })
1453    }
1454}
1455
1456impl IntoV2 for crate::v1::AvailableCommandInput {
1457    type Output = super::AvailableCommandInput;
1458
1459    fn into_v2(self) -> Result<Self::Output> {
1460        Ok(match self {
1461            Self::Unstructured(value) => super::AvailableCommandInput::Text(value.into_v2()?),
1462        })
1463    }
1464}
1465
1466impl IntoV1 for super::TextCommandInput {
1467    type Output = crate::v1::UnstructuredCommandInput;
1468
1469    fn into_v1(self) -> Result<Self::Output> {
1470        let Self { hint, meta } = self;
1471        Ok(crate::v1::UnstructuredCommandInput {
1472            hint: hint.into_v1()?,
1473            meta: meta.into_v1()?,
1474        })
1475    }
1476}
1477
1478impl IntoV2 for crate::v1::UnstructuredCommandInput {
1479    type Output = super::TextCommandInput;
1480
1481    fn into_v2(self) -> Result<Self::Output> {
1482        let Self { hint, meta } = self;
1483        Ok(super::TextCommandInput {
1484            hint: hint.into_v2()?,
1485            meta: meta.into_v2()?,
1486        })
1487    }
1488}
1489
1490impl IntoV1 for super::RequestPermissionRequest {
1491    type Output = crate::v1::RequestPermissionRequest;
1492
1493    fn into_v1(self) -> Result<Self::Output> {
1494        let Self {
1495            session_id,
1496            title: _,
1497            description: _,
1498            subject,
1499            options,
1500            meta,
1501        } = self;
1502        let Some(subject) = subject else {
1503            return Err(ProtocolConversionError::new(
1504                "v2 RequestPermissionRequest without `subject` cannot be represented in v1",
1505            ));
1506        };
1507        let tool_call = match subject {
1508            super::RequestPermissionSubject::ToolCall(subject) => {
1509                let super::ToolCallPermissionSubject { tool_call } = *subject;
1510                tool_call
1511            }
1512            super::RequestPermissionSubject::Other(subject) => {
1513                return Err(unknown_v2_enum_variant(
1514                    "RequestPermissionSubject",
1515                    &subject.type_,
1516                ));
1517            }
1518        };
1519        Ok(crate::v1::RequestPermissionRequest {
1520            session_id: session_id.into_v1()?,
1521            tool_call: tool_call.into_v1()?,
1522            options: options.into_v1()?,
1523            meta: meta.into_v1()?,
1524        })
1525    }
1526}
1527
1528impl IntoV2 for crate::v1::RequestPermissionRequest {
1529    type Output = super::RequestPermissionRequest;
1530
1531    fn into_v2(self) -> Result<Self::Output> {
1532        let Self {
1533            session_id,
1534            tool_call,
1535            options,
1536            meta,
1537        } = self;
1538        let title = tool_call
1539            .fields
1540            .title
1541            .clone()
1542            .filter(|title| !title.is_empty())
1543            .unwrap_or_else(|| "Permission requested".to_string());
1544        Ok(super::RequestPermissionRequest {
1545            session_id: session_id.into_v2()?,
1546            title,
1547            description: None,
1548            subject: Some(super::RequestPermissionSubject::from(tool_call.into_v2()?)),
1549            options: options.into_v2()?,
1550            meta: meta.into_v2()?,
1551        })
1552    }
1553}
1554
1555impl IntoV1 for super::PermissionOption {
1556    type Output = crate::v1::PermissionOption;
1557
1558    fn into_v1(self) -> Result<Self::Output> {
1559        let Self {
1560            option_id,
1561            name,
1562            kind,
1563            meta,
1564        } = self;
1565        Ok(crate::v1::PermissionOption {
1566            option_id: option_id.into_v1()?,
1567            name: name.into_v1()?,
1568            kind: kind.into_v1()?,
1569            meta: meta.into_v1()?,
1570        })
1571    }
1572}
1573
1574impl IntoV2 for crate::v1::PermissionOption {
1575    type Output = super::PermissionOption;
1576
1577    fn into_v2(self) -> Result<Self::Output> {
1578        let Self {
1579            option_id,
1580            name,
1581            kind,
1582            meta,
1583        } = self;
1584        Ok(super::PermissionOption {
1585            option_id: option_id.into_v2()?,
1586            name: name.into_v2()?,
1587            kind: kind.into_v2()?,
1588            meta: meta.into_v2()?,
1589        })
1590    }
1591}
1592
1593impl IntoV1 for super::PermissionOptionId {
1594    type Output = crate::v1::PermissionOptionId;
1595
1596    fn into_v1(self) -> Result<Self::Output> {
1597        Ok(crate::v1::PermissionOptionId(self.0.into_v1()?))
1598    }
1599}
1600
1601impl IntoV2 for crate::v1::PermissionOptionId {
1602    type Output = super::PermissionOptionId;
1603
1604    fn into_v2(self) -> Result<Self::Output> {
1605        Ok(super::PermissionOptionId(self.0.into_v2()?))
1606    }
1607}
1608
1609impl IntoV1 for super::PermissionOptionKind {
1610    type Output = crate::v1::PermissionOptionKind;
1611
1612    fn into_v1(self) -> Result<Self::Output> {
1613        Ok(match self {
1614            Self::AllowOnce => crate::v1::PermissionOptionKind::AllowOnce,
1615            Self::AllowAlways => crate::v1::PermissionOptionKind::AllowAlways,
1616            Self::RejectOnce => crate::v1::PermissionOptionKind::RejectOnce,
1617            Self::RejectAlways => crate::v1::PermissionOptionKind::RejectAlways,
1618            Self::Other(value) => {
1619                return Err(unknown_v2_enum_variant("PermissionOptionKind", &value));
1620            }
1621        })
1622    }
1623}
1624
1625impl IntoV2 for crate::v1::PermissionOptionKind {
1626    type Output = super::PermissionOptionKind;
1627
1628    fn into_v2(self) -> Result<Self::Output> {
1629        Ok(match self {
1630            Self::AllowOnce => super::PermissionOptionKind::AllowOnce,
1631            Self::AllowAlways => super::PermissionOptionKind::AllowAlways,
1632            Self::RejectOnce => super::PermissionOptionKind::RejectOnce,
1633            Self::RejectAlways => super::PermissionOptionKind::RejectAlways,
1634        })
1635    }
1636}
1637
1638impl IntoV1 for super::RequestPermissionResponse {
1639    type Output = crate::v1::RequestPermissionResponse;
1640
1641    fn into_v1(self) -> Result<Self::Output> {
1642        let Self { outcome, meta } = self;
1643        Ok(crate::v1::RequestPermissionResponse {
1644            outcome: outcome.into_v1()?,
1645            meta: meta.into_v1()?,
1646        })
1647    }
1648}
1649
1650impl IntoV2 for crate::v1::RequestPermissionResponse {
1651    type Output = super::RequestPermissionResponse;
1652
1653    fn into_v2(self) -> Result<Self::Output> {
1654        let Self { outcome, meta } = self;
1655        Ok(super::RequestPermissionResponse {
1656            outcome: outcome.into_v2()?,
1657            meta: meta.into_v2()?,
1658        })
1659    }
1660}
1661
1662impl IntoV1 for super::RequestPermissionOutcome {
1663    type Output = crate::v1::RequestPermissionOutcome;
1664
1665    fn into_v1(self) -> Result<Self::Output> {
1666        Ok(match self {
1667            Self::Cancelled => crate::v1::RequestPermissionOutcome::Cancelled,
1668            Self::Selected(value) => {
1669                crate::v1::RequestPermissionOutcome::Selected(value.into_v1()?)
1670            }
1671            Self::Other(value) => {
1672                return Err(unknown_v2_enum_variant(
1673                    "RequestPermissionOutcome",
1674                    &value.outcome,
1675                ));
1676            }
1677        })
1678    }
1679}
1680
1681impl IntoV2 for crate::v1::RequestPermissionOutcome {
1682    type Output = super::RequestPermissionOutcome;
1683
1684    fn into_v2(self) -> Result<Self::Output> {
1685        Ok(match self {
1686            Self::Cancelled => super::RequestPermissionOutcome::Cancelled,
1687            Self::Selected(value) => super::RequestPermissionOutcome::Selected(value.into_v2()?),
1688        })
1689    }
1690}
1691
1692impl IntoV1 for super::SelectedPermissionOutcome {
1693    type Output = crate::v1::SelectedPermissionOutcome;
1694
1695    fn into_v1(self) -> Result<Self::Output> {
1696        let Self { option_id, meta } = self;
1697        Ok(crate::v1::SelectedPermissionOutcome {
1698            option_id: option_id.into_v1()?,
1699            meta: meta.into_v1()?,
1700        })
1701    }
1702}
1703
1704impl IntoV2 for crate::v1::SelectedPermissionOutcome {
1705    type Output = super::SelectedPermissionOutcome;
1706
1707    fn into_v2(self) -> Result<Self::Output> {
1708        let Self { option_id, meta } = self;
1709        Ok(super::SelectedPermissionOutcome {
1710            option_id: option_id.into_v2()?,
1711            meta: meta.into_v2()?,
1712        })
1713    }
1714}
1715
1716#[cfg(feature = "unstable_mcp_over_acp")]
1717impl IntoV1 for super::ConnectMcpRequest {
1718    type Output = crate::v1::ConnectMcpRequest;
1719
1720    fn into_v1(self) -> Result<Self::Output> {
1721        let Self { server_id, meta } = self;
1722        Ok(crate::v1::ConnectMcpRequest {
1723            server_id: server_id.into_v1()?,
1724            meta: meta.into_v1()?,
1725        })
1726    }
1727}
1728
1729#[cfg(feature = "unstable_mcp_over_acp")]
1730impl IntoV2 for crate::v1::ConnectMcpRequest {
1731    type Output = super::ConnectMcpRequest;
1732
1733    fn into_v2(self) -> Result<Self::Output> {
1734        let Self { server_id, meta } = self;
1735        Ok(super::ConnectMcpRequest {
1736            server_id: server_id.into_v2()?,
1737            meta: meta.into_v2()?,
1738        })
1739    }
1740}
1741
1742#[cfg(feature = "unstable_mcp_over_acp")]
1743impl IntoV1 for super::ConnectMcpResponse {
1744    type Output = crate::v1::ConnectMcpResponse;
1745
1746    fn into_v1(self) -> Result<Self::Output> {
1747        let Self {
1748            connection_id,
1749            meta,
1750        } = self;
1751        Ok(crate::v1::ConnectMcpResponse {
1752            connection_id: connection_id.into_v1()?,
1753            meta: meta.into_v1()?,
1754        })
1755    }
1756}
1757
1758#[cfg(feature = "unstable_mcp_over_acp")]
1759impl IntoV2 for crate::v1::ConnectMcpResponse {
1760    type Output = super::ConnectMcpResponse;
1761
1762    fn into_v2(self) -> Result<Self::Output> {
1763        let Self {
1764            connection_id,
1765            meta,
1766        } = self;
1767        Ok(super::ConnectMcpResponse {
1768            connection_id: connection_id.into_v2()?,
1769            meta: meta.into_v2()?,
1770        })
1771    }
1772}
1773
1774#[cfg(feature = "unstable_mcp_over_acp")]
1775impl IntoV1 for super::MessageMcpRequest {
1776    type Output = crate::v1::MessageMcpRequest;
1777
1778    fn into_v1(self) -> Result<Self::Output> {
1779        let Self {
1780            connection_id,
1781            method,
1782            params,
1783            meta,
1784        } = self;
1785        Ok(crate::v1::MessageMcpRequest {
1786            connection_id: connection_id.into_v1()?,
1787            method: method.into_v1()?,
1788            params: params.into_v1()?,
1789            meta: meta.into_v1()?,
1790        })
1791    }
1792}
1793
1794#[cfg(feature = "unstable_mcp_over_acp")]
1795impl IntoV2 for crate::v1::MessageMcpRequest {
1796    type Output = super::MessageMcpRequest;
1797
1798    fn into_v2(self) -> Result<Self::Output> {
1799        let Self {
1800            connection_id,
1801            method,
1802            params,
1803            meta,
1804        } = self;
1805        Ok(super::MessageMcpRequest {
1806            connection_id: connection_id.into_v2()?,
1807            method: method.into_v2()?,
1808            params: params.into_v2()?,
1809            meta: meta.into_v2()?,
1810        })
1811    }
1812}
1813
1814#[cfg(feature = "unstable_mcp_over_acp")]
1815impl IntoV1 for super::MessageMcpNotification {
1816    type Output = crate::v1::MessageMcpNotification;
1817
1818    fn into_v1(self) -> Result<Self::Output> {
1819        let Self {
1820            connection_id,
1821            method,
1822            params,
1823            meta,
1824        } = self;
1825        Ok(crate::v1::MessageMcpNotification {
1826            connection_id: connection_id.into_v1()?,
1827            method: method.into_v1()?,
1828            params: params.into_v1()?,
1829            meta: meta.into_v1()?,
1830        })
1831    }
1832}
1833
1834#[cfg(feature = "unstable_mcp_over_acp")]
1835impl IntoV2 for crate::v1::MessageMcpNotification {
1836    type Output = super::MessageMcpNotification;
1837
1838    fn into_v2(self) -> Result<Self::Output> {
1839        let Self {
1840            connection_id,
1841            method,
1842            params,
1843            meta,
1844        } = self;
1845        Ok(super::MessageMcpNotification {
1846            connection_id: connection_id.into_v2()?,
1847            method: method.into_v2()?,
1848            params: params.into_v2()?,
1849            meta: meta.into_v2()?,
1850        })
1851    }
1852}
1853
1854#[cfg(feature = "unstable_mcp_over_acp")]
1855impl IntoV1 for super::MessageMcpResponse {
1856    type Output = crate::v1::MessageMcpResponse;
1857
1858    fn into_v1(self) -> Result<Self::Output> {
1859        let Self(result) = self;
1860        Ok(crate::v1::MessageMcpResponse::new(result.into_v1()?))
1861    }
1862}
1863
1864#[cfg(feature = "unstable_mcp_over_acp")]
1865impl IntoV2 for crate::v1::MessageMcpResponse {
1866    type Output = super::MessageMcpResponse;
1867
1868    fn into_v2(self) -> Result<Self::Output> {
1869        let Self(result) = self;
1870        Ok(super::MessageMcpResponse::new(result.into_v2()?))
1871    }
1872}
1873
1874#[cfg(feature = "unstable_mcp_over_acp")]
1875impl IntoV1 for super::DisconnectMcpRequest {
1876    type Output = crate::v1::DisconnectMcpRequest;
1877
1878    fn into_v1(self) -> Result<Self::Output> {
1879        let Self {
1880            connection_id,
1881            meta,
1882        } = self;
1883        Ok(crate::v1::DisconnectMcpRequest {
1884            connection_id: connection_id.into_v1()?,
1885            meta: meta.into_v1()?,
1886        })
1887    }
1888}
1889
1890#[cfg(feature = "unstable_mcp_over_acp")]
1891impl IntoV2 for crate::v1::DisconnectMcpRequest {
1892    type Output = super::DisconnectMcpRequest;
1893
1894    fn into_v2(self) -> Result<Self::Output> {
1895        let Self {
1896            connection_id,
1897            meta,
1898        } = self;
1899        Ok(super::DisconnectMcpRequest {
1900            connection_id: connection_id.into_v2()?,
1901            meta: meta.into_v2()?,
1902        })
1903    }
1904}
1905
1906#[cfg(feature = "unstable_mcp_over_acp")]
1907impl IntoV1 for super::DisconnectMcpResponse {
1908    type Output = crate::v1::DisconnectMcpResponse;
1909
1910    fn into_v1(self) -> Result<Self::Output> {
1911        let Self { meta } = self;
1912        Ok(crate::v1::DisconnectMcpResponse {
1913            meta: meta.into_v1()?,
1914        })
1915    }
1916}
1917
1918#[cfg(feature = "unstable_mcp_over_acp")]
1919impl IntoV2 for crate::v1::DisconnectMcpResponse {
1920    type Output = super::DisconnectMcpResponse;
1921
1922    fn into_v2(self) -> Result<Self::Output> {
1923        let Self { meta } = self;
1924        Ok(super::DisconnectMcpResponse {
1925            meta: meta.into_v2()?,
1926        })
1927    }
1928}
1929
1930impl IntoV1 for super::ClientCapabilities {
1931    type Output = crate::v1::ClientCapabilities;
1932
1933    fn into_v1(self) -> Result<Self::Output> {
1934        let Self {
1935            #[cfg(feature = "unstable_auth_methods")]
1936            auth,
1937            #[cfg(feature = "unstable_elicitation")]
1938            elicitation,
1939            #[cfg(feature = "unstable_nes")]
1940            nes,
1941            #[cfg(feature = "unstable_nes")]
1942            position_encodings,
1943            meta,
1944        } = self;
1945        Ok(crate::v1::ClientCapabilities {
1946            fs: crate::v1::FileSystemCapabilities::default(),
1947            terminal: false,
1948            session: Some(
1949                crate::v1::ClientSessionCapabilities::new().config_options(
1950                    crate::v1::SessionConfigOptionsCapabilities::new()
1951                        .boolean(crate::v1::BooleanConfigOptionCapabilities::new()),
1952                ),
1953            ),
1954            #[cfg(feature = "unstable_plan_operations")]
1955            plan: None,
1956            #[cfg(feature = "unstable_auth_methods")]
1957            auth: auth.map(IntoV1::into_v1).transpose()?.unwrap_or_default(),
1958            #[cfg(feature = "unstable_elicitation")]
1959            elicitation: into_v1_default_on_error(elicitation),
1960            #[cfg(feature = "unstable_nes")]
1961            nes: into_v1_default_on_error(nes),
1962            #[cfg(feature = "unstable_nes")]
1963            position_encodings: into_v1_vec_skip_errors(position_encodings),
1964            meta: meta.into_v1()?,
1965        })
1966    }
1967}
1968
1969impl IntoV2 for crate::v1::ClientCapabilities {
1970    type Output = super::ClientCapabilities;
1971
1972    fn into_v2(self) -> Result<Self::Output> {
1973        let Self {
1974            fs: _,
1975            terminal: _,
1976            session: _,
1977            #[cfg(feature = "unstable_plan_operations")]
1978                plan: _,
1979            #[cfg(feature = "unstable_auth_methods")]
1980            auth,
1981            #[cfg(feature = "unstable_elicitation")]
1982            elicitation,
1983            #[cfg(feature = "unstable_nes")]
1984            nes,
1985            #[cfg(feature = "unstable_nes")]
1986            position_encodings,
1987            meta,
1988        } = self;
1989        Ok(super::ClientCapabilities {
1990            #[cfg(feature = "unstable_auth_methods")]
1991            auth: Some(auth.into_v2()?),
1992            #[cfg(feature = "unstable_elicitation")]
1993            elicitation: into_v2_default_on_error(elicitation),
1994            #[cfg(feature = "unstable_nes")]
1995            nes: into_v2_default_on_error(nes),
1996            #[cfg(feature = "unstable_nes")]
1997            position_encodings: into_v2_vec_skip_errors(position_encodings),
1998            meta: meta.into_v2()?,
1999        })
2000    }
2001}
2002
2003#[cfg(feature = "unstable_auth_methods")]
2004impl IntoV1 for super::AuthCapabilities {
2005    type Output = crate::v1::AuthCapabilities;
2006
2007    fn into_v1(self) -> Result<Self::Output> {
2008        let Self { terminal, meta } = self;
2009        Ok(crate::v1::AuthCapabilities {
2010            terminal: terminal.is_some(),
2011            meta: meta.into_v1()?,
2012        })
2013    }
2014}
2015
2016#[cfg(feature = "unstable_auth_methods")]
2017impl IntoV2 for crate::v1::AuthCapabilities {
2018    type Output = super::AuthCapabilities;
2019
2020    fn into_v2(self) -> Result<Self::Output> {
2021        let Self { terminal, meta } = self;
2022        Ok(super::AuthCapabilities {
2023            terminal: terminal.then(super::TerminalAuthCapabilities::new),
2024            meta: meta.into_v2()?,
2025        })
2026    }
2027}
2028
2029impl IntoV1 for super::AgentRequest {
2030    type Output = crate::v1::AgentRequest;
2031
2032    fn into_v1(self) -> Result<Self::Output> {
2033        Ok(match self {
2034            Self::RequestPermissionRequest(value) => {
2035                crate::v1::AgentRequest::RequestPermissionRequest(value.into_v1()?)
2036            }
2037            #[cfg(feature = "unstable_elicitation")]
2038            Self::CreateElicitationRequest(value) => {
2039                crate::v1::AgentRequest::CreateElicitationRequest(value.into_v1()?)
2040            }
2041            #[cfg(feature = "unstable_mcp_over_acp")]
2042            Self::ConnectMcpRequest(value) => {
2043                crate::v1::AgentRequest::ConnectMcpRequest(value.into_v1()?)
2044            }
2045            #[cfg(feature = "unstable_mcp_over_acp")]
2046            Self::MessageMcpRequest(value) => {
2047                crate::v1::AgentRequest::MessageMcpRequest(value.into_v1()?)
2048            }
2049            #[cfg(feature = "unstable_mcp_over_acp")]
2050            Self::DisconnectMcpRequest(value) => {
2051                crate::v1::AgentRequest::DisconnectMcpRequest(value.into_v1()?)
2052            }
2053            Self::ExtMethodRequest(value) => {
2054                crate::v1::AgentRequest::ExtMethodRequest(value.into_v1()?)
2055            }
2056        })
2057    }
2058}
2059
2060impl IntoV2 for crate::v1::AgentRequest {
2061    type Output = super::AgentRequest;
2062
2063    fn into_v2(self) -> Result<Self::Output> {
2064        Ok(match self {
2065            Self::WriteTextFileRequest(_) => {
2066                return Err(removed_v1_enum_variant(
2067                    "AgentRequest",
2068                    "fs/write_text_file",
2069                ));
2070            }
2071            Self::ReadTextFileRequest(_) => {
2072                return Err(removed_v1_enum_variant("AgentRequest", "fs/read_text_file"));
2073            }
2074            Self::RequestPermissionRequest(value) => {
2075                super::AgentRequest::RequestPermissionRequest(Box::new(value.into_v2()?))
2076            }
2077            Self::CreateTerminalRequest(_) => {
2078                return Err(removed_v1_enum_variant("AgentRequest", "terminal/create"));
2079            }
2080            Self::TerminalOutputRequest(_) => {
2081                return Err(removed_v1_enum_variant("AgentRequest", "terminal/output"));
2082            }
2083            Self::ReleaseTerminalRequest(_) => {
2084                return Err(removed_v1_enum_variant("AgentRequest", "terminal/release"));
2085            }
2086            Self::WaitForTerminalExitRequest(_) => {
2087                return Err(removed_v1_enum_variant(
2088                    "AgentRequest",
2089                    "terminal/wait_for_exit",
2090                ));
2091            }
2092            Self::KillTerminalRequest(_) => {
2093                return Err(removed_v1_enum_variant("AgentRequest", "terminal/kill"));
2094            }
2095            #[cfg(feature = "unstable_elicitation")]
2096            Self::CreateElicitationRequest(value) => {
2097                super::AgentRequest::CreateElicitationRequest(Box::new(value.into_v2()?))
2098            }
2099            #[cfg(feature = "unstable_mcp_over_acp")]
2100            Self::ConnectMcpRequest(value) => {
2101                super::AgentRequest::ConnectMcpRequest(Box::new(value.into_v2()?))
2102            }
2103            #[cfg(feature = "unstable_mcp_over_acp")]
2104            Self::MessageMcpRequest(value) => {
2105                super::AgentRequest::MessageMcpRequest(Box::new(value.into_v2()?))
2106            }
2107            #[cfg(feature = "unstable_mcp_over_acp")]
2108            Self::DisconnectMcpRequest(value) => {
2109                super::AgentRequest::DisconnectMcpRequest(Box::new(value.into_v2()?))
2110            }
2111            Self::ExtMethodRequest(value) => {
2112                super::AgentRequest::ExtMethodRequest(Box::new(value.into_v2()?))
2113            }
2114        })
2115    }
2116}
2117
2118impl IntoV1 for super::ClientResponse {
2119    type Output = crate::v1::ClientResponse;
2120
2121    fn into_v1(self) -> Result<Self::Output> {
2122        Ok(match self {
2123            Self::RequestPermissionResponse(value) => {
2124                crate::v1::ClientResponse::RequestPermissionResponse(value.into_v1()?)
2125            }
2126            #[cfg(feature = "unstable_elicitation")]
2127            Self::CreateElicitationResponse(value) => {
2128                crate::v1::ClientResponse::CreateElicitationResponse(value.into_v1()?)
2129            }
2130            #[cfg(feature = "unstable_mcp_over_acp")]
2131            Self::ConnectMcpResponse(value) => {
2132                crate::v1::ClientResponse::ConnectMcpResponse(value.into_v1()?)
2133            }
2134            #[cfg(feature = "unstable_mcp_over_acp")]
2135            Self::MessageMcpResponse(value) => {
2136                crate::v1::ClientResponse::MessageMcpResponse(value.into_v1()?)
2137            }
2138            #[cfg(feature = "unstable_mcp_over_acp")]
2139            Self::DisconnectMcpResponse(value) => {
2140                crate::v1::ClientResponse::DisconnectMcpResponse(value.into_v1()?)
2141            }
2142            Self::ExtMethodResponse(value) => {
2143                crate::v1::ClientResponse::ExtMethodResponse(value.into_v1()?)
2144            }
2145        })
2146    }
2147}
2148
2149impl IntoV2 for crate::v1::ClientResponse {
2150    type Output = super::ClientResponse;
2151
2152    fn into_v2(self) -> Result<Self::Output> {
2153        Ok(match self {
2154            Self::WriteTextFileResponse(_) => {
2155                return Err(removed_v1_enum_variant(
2156                    "ClientResponse",
2157                    "fs/write_text_file",
2158                ));
2159            }
2160            Self::ReadTextFileResponse(_) => {
2161                return Err(removed_v1_enum_variant(
2162                    "ClientResponse",
2163                    "fs/read_text_file",
2164                ));
2165            }
2166            Self::RequestPermissionResponse(value) => {
2167                super::ClientResponse::RequestPermissionResponse(Box::new(value.into_v2()?))
2168            }
2169            Self::CreateTerminalResponse(_) => {
2170                return Err(removed_v1_enum_variant("ClientResponse", "terminal/create"));
2171            }
2172            Self::TerminalOutputResponse(_) => {
2173                return Err(removed_v1_enum_variant("ClientResponse", "terminal/output"));
2174            }
2175            Self::ReleaseTerminalResponse(_) => {
2176                return Err(removed_v1_enum_variant(
2177                    "ClientResponse",
2178                    "terminal/release",
2179                ));
2180            }
2181            Self::WaitForTerminalExitResponse(_) => {
2182                return Err(removed_v1_enum_variant(
2183                    "ClientResponse",
2184                    "terminal/wait_for_exit",
2185                ));
2186            }
2187            Self::KillTerminalResponse(_) => {
2188                return Err(removed_v1_enum_variant("ClientResponse", "terminal/kill"));
2189            }
2190            #[cfg(feature = "unstable_elicitation")]
2191            Self::CreateElicitationResponse(value) => {
2192                super::ClientResponse::CreateElicitationResponse(Box::new(value.into_v2()?))
2193            }
2194            #[cfg(feature = "unstable_mcp_over_acp")]
2195            Self::ConnectMcpResponse(value) => {
2196                super::ClientResponse::ConnectMcpResponse(Box::new(value.into_v2()?))
2197            }
2198            #[cfg(feature = "unstable_mcp_over_acp")]
2199            Self::MessageMcpResponse(value) => {
2200                super::ClientResponse::MessageMcpResponse(Box::new(value.into_v2()?))
2201            }
2202            #[cfg(feature = "unstable_mcp_over_acp")]
2203            Self::DisconnectMcpResponse(value) => {
2204                super::ClientResponse::DisconnectMcpResponse(Box::new(value.into_v2()?))
2205            }
2206            Self::ExtMethodResponse(value) => {
2207                super::ClientResponse::ExtMethodResponse(Box::new(value.into_v2()?))
2208            }
2209        })
2210    }
2211}
2212
2213impl IntoV1Many for super::AgentNotification {
2214    type Output = crate::v1::AgentNotification;
2215
2216    fn into_v1_many(self) -> Result<Vec<Self::Output>> {
2217        Ok(match self {
2218            Self::UpdateSessionNotification(value) => {
2219                return value
2220                    .into_v1_many()?
2221                    .into_iter()
2222                    .map(|value| Ok(crate::v1::AgentNotification::SessionNotification(value)))
2223                    .collect();
2224            }
2225            #[cfg(feature = "unstable_elicitation")]
2226            Self::CompleteElicitationNotification(value) => {
2227                vec![
2228                    crate::v1::AgentNotification::CompleteElicitationNotification(value.into_v1()?),
2229                ]
2230            }
2231            #[cfg(feature = "unstable_mcp_over_acp")]
2232            Self::MessageMcpNotification(value) => {
2233                vec![crate::v1::AgentNotification::MessageMcpNotification(
2234                    value.into_v1()?,
2235                )]
2236            }
2237            Self::ExtNotification(value) => {
2238                vec![crate::v1::AgentNotification::ExtNotification(
2239                    value.into_v1()?,
2240                )]
2241            }
2242        })
2243    }
2244}
2245
2246impl IntoV2 for crate::v1::AgentNotification {
2247    type Output = super::AgentNotification;
2248
2249    fn into_v2(self) -> Result<Self::Output> {
2250        Ok(match self {
2251            Self::SessionNotification(value) => {
2252                super::AgentNotification::UpdateSessionNotification(Box::new(value.into_v2()?))
2253            }
2254            #[cfg(feature = "unstable_elicitation")]
2255            Self::CompleteElicitationNotification(value) => {
2256                super::AgentNotification::CompleteElicitationNotification(Box::new(
2257                    value.into_v2()?,
2258                ))
2259            }
2260            #[cfg(feature = "unstable_mcp_over_acp")]
2261            Self::MessageMcpNotification(value) => {
2262                super::AgentNotification::MessageMcpNotification(Box::new(value.into_v2()?))
2263            }
2264            Self::ExtNotification(value) => {
2265                super::AgentNotification::ExtNotification(Box::new(value.into_v2()?))
2266            }
2267        })
2268    }
2269}
2270
2271impl IntoV1 for super::Error {
2272    type Output = crate::v1::Error;
2273
2274    fn into_v1(self) -> Result<Self::Output> {
2275        let Self {
2276            code,
2277            message,
2278            data,
2279        } = self;
2280        Ok(crate::v1::Error {
2281            code: code.into_v1()?,
2282            message: message.into_v1()?,
2283            data: data.into_v1()?,
2284        })
2285    }
2286}
2287
2288impl IntoV2 for crate::v1::Error {
2289    type Output = super::Error;
2290
2291    fn into_v2(self) -> Result<Self::Output> {
2292        let Self {
2293            code,
2294            message,
2295            data,
2296        } = self;
2297        Ok(super::Error {
2298            code: code.into_v2()?,
2299            message: message.into_v2()?,
2300            data: data.into_v2()?,
2301        })
2302    }
2303}
2304
2305impl IntoV1 for super::ErrorCode {
2306    type Output = crate::v1::ErrorCode;
2307
2308    fn into_v1(self) -> Result<Self::Output> {
2309        Ok(i32::from(self).into())
2310    }
2311}
2312
2313impl IntoV2 for crate::v1::ErrorCode {
2314    type Output = super::ErrorCode;
2315
2316    fn into_v2(self) -> Result<Self::Output> {
2317        Ok(i32::from(self).into())
2318    }
2319}
2320
2321impl IntoV1 for super::ExtRequest {
2322    type Output = crate::v1::ExtRequest;
2323
2324    fn into_v1(self) -> Result<Self::Output> {
2325        let Self { method, params } = self;
2326        Ok(crate::v1::ExtRequest {
2327            method: method.into_v1()?,
2328            params: params.into_v1()?,
2329        })
2330    }
2331}
2332
2333impl IntoV2 for crate::v1::ExtRequest {
2334    type Output = super::ExtRequest;
2335
2336    fn into_v2(self) -> Result<Self::Output> {
2337        let Self { method, params } = self;
2338        Ok(super::ExtRequest {
2339            method: method.into_v2()?,
2340            params: params.into_v2()?,
2341        })
2342    }
2343}
2344
2345impl IntoV1 for super::ExtResponse {
2346    type Output = crate::v1::ExtResponse;
2347
2348    fn into_v1(self) -> Result<Self::Output> {
2349        Ok(crate::v1::ExtResponse(self.0.into_v1()?))
2350    }
2351}
2352
2353impl IntoV2 for crate::v1::ExtResponse {
2354    type Output = super::ExtResponse;
2355
2356    fn into_v2(self) -> Result<Self::Output> {
2357        Ok(super::ExtResponse(self.0.into_v2()?))
2358    }
2359}
2360
2361impl IntoV1 for super::ExtNotification {
2362    type Output = crate::v1::ExtNotification;
2363
2364    fn into_v1(self) -> Result<Self::Output> {
2365        let Self { method, params } = self;
2366        Ok(crate::v1::ExtNotification {
2367            method: method.into_v1()?,
2368            params: params.into_v1()?,
2369        })
2370    }
2371}
2372
2373impl IntoV2 for crate::v1::ExtNotification {
2374    type Output = super::ExtNotification;
2375
2376    fn into_v2(self) -> Result<Self::Output> {
2377        let Self { method, params } = self;
2378        Ok(super::ExtNotification {
2379            method: method.into_v2()?,
2380            params: params.into_v2()?,
2381        })
2382    }
2383}
2384
2385fn maybe_undefined_value_into_v1_option<T>(value: crate::MaybeUndefined<T>) -> Option<T::Output>
2386where
2387    T: IntoV1,
2388{
2389    match value {
2390        crate::MaybeUndefined::Value(value) => value.into_v1().ok(),
2391        crate::MaybeUndefined::Null | crate::MaybeUndefined::Undefined => None,
2392    }
2393}
2394
2395fn maybe_undefined_vec_into_v1_option<T>(
2396    value: crate::MaybeUndefined<Vec<T>>,
2397) -> Option<Vec<T::Output>>
2398where
2399    T: IntoV1,
2400{
2401    match value {
2402        crate::MaybeUndefined::Value(value) => Some(into_v1_vec_skip_errors(value)),
2403        crate::MaybeUndefined::Null => Some(Vec::new()),
2404        crate::MaybeUndefined::Undefined => None,
2405    }
2406}
2407
2408fn maybe_undefined_meta_into_v1_option(
2409    context: &str,
2410    value: crate::MaybeUndefined<super::Meta>,
2411) -> Result<Option<crate::v1::Meta>> {
2412    match value {
2413        crate::MaybeUndefined::Value(value) => Ok(Some(value.into_v1()?)),
2414        crate::MaybeUndefined::Null => Err(ProtocolConversionError::new(format!(
2415            "v2 {context} with null _meta cannot be represented in v1"
2416        ))),
2417        crate::MaybeUndefined::Undefined => Ok(None),
2418    }
2419}
2420
2421fn option_into_v2_maybe_undefined<T>(value: Option<T>) -> Result<crate::MaybeUndefined<T::Output>>
2422where
2423    T: IntoV2,
2424{
2425    match value {
2426        Some(value) => Ok(crate::MaybeUndefined::Value(value.into_v2()?)),
2427        None => Ok(crate::MaybeUndefined::Undefined),
2428    }
2429}
2430
2431fn option_vec_into_v2_maybe_undefined_skip_errors<T>(
2432    value: Option<Vec<T>>,
2433) -> crate::MaybeUndefined<Vec<T::Output>>
2434where
2435    T: IntoV2,
2436{
2437    match value {
2438        Some(value) => crate::MaybeUndefined::Value(into_v2_vec_skip_errors(value)),
2439        None => crate::MaybeUndefined::Undefined,
2440    }
2441}
2442
2443fn vec_into_v2_maybe_undefined_skip_errors<T>(
2444    value: Vec<T>,
2445) -> crate::MaybeUndefined<Vec<T::Output>>
2446where
2447    T: IntoV2,
2448{
2449    if value.is_empty() {
2450        crate::MaybeUndefined::Undefined
2451    } else {
2452        crate::MaybeUndefined::Value(into_v2_vec_skip_errors(value))
2453    }
2454}
2455
2456impl IntoV1 for super::ToolCallUpdate {
2457    type Output = crate::v1::ToolCallUpdate;
2458
2459    fn into_v1(self) -> Result<Self::Output> {
2460        let Self {
2461            tool_call_id,
2462            title,
2463            kind,
2464            status,
2465            content,
2466            locations,
2467            raw_input,
2468            raw_output,
2469            meta,
2470        } = self;
2471        Ok(crate::v1::ToolCallUpdate {
2472            tool_call_id: tool_call_id.into_v1()?,
2473            fields: crate::v1::ToolCallUpdateFields {
2474                kind: maybe_undefined_value_into_v1_option(kind),
2475                status: maybe_undefined_value_into_v1_option(status),
2476                title: maybe_undefined_value_into_v1_option(title),
2477                content: maybe_undefined_vec_into_v1_option(content),
2478                locations: maybe_undefined_vec_into_v1_option(locations),
2479                raw_input: maybe_undefined_value_into_v1_option(raw_input),
2480                raw_output: maybe_undefined_value_into_v1_option(raw_output),
2481            },
2482            meta: maybe_undefined_meta_into_v1_option("ToolCallUpdate", meta)?,
2483        })
2484    }
2485}
2486
2487impl IntoV2 for crate::v1::ToolCall {
2488    type Output = super::ToolCallUpdate;
2489
2490    fn into_v2(self) -> Result<Self::Output> {
2491        let Self {
2492            tool_call_id,
2493            title,
2494            kind,
2495            status,
2496            content,
2497            locations,
2498            raw_input,
2499            raw_output,
2500            meta,
2501        } = self;
2502        Ok(super::ToolCallUpdate {
2503            tool_call_id: tool_call_id.into_v2()?,
2504            title: crate::MaybeUndefined::Value(title.into_v2()?),
2505            kind: if matches!(kind, crate::v1::ToolKind::Other) {
2506                crate::MaybeUndefined::Undefined
2507            } else {
2508                crate::MaybeUndefined::Value(kind.into_v2()?)
2509            },
2510            status: if matches!(status, crate::v1::ToolCallStatus::Pending) {
2511                crate::MaybeUndefined::Undefined
2512            } else {
2513                crate::MaybeUndefined::Value(status.into_v2()?)
2514            },
2515            content: vec_into_v2_maybe_undefined_skip_errors(content),
2516            locations: vec_into_v2_maybe_undefined_skip_errors(locations),
2517            raw_input: option_into_v2_maybe_undefined(raw_input)?,
2518            raw_output: option_into_v2_maybe_undefined(raw_output)?,
2519            meta: option_into_v2_maybe_undefined(meta)?,
2520        })
2521    }
2522}
2523
2524impl IntoV2 for crate::v1::ToolCallUpdate {
2525    type Output = super::ToolCallUpdate;
2526
2527    fn into_v2(self) -> Result<Self::Output> {
2528        let Self {
2529            tool_call_id,
2530            fields,
2531            meta,
2532        } = self;
2533        let crate::v1::ToolCallUpdateFields {
2534            kind,
2535            status,
2536            title,
2537            content,
2538            locations,
2539            raw_input,
2540            raw_output,
2541        } = fields;
2542        Ok(super::ToolCallUpdate {
2543            tool_call_id: tool_call_id.into_v2()?,
2544            kind: option_into_v2_maybe_undefined(kind)?,
2545            status: option_into_v2_maybe_undefined(status)?,
2546            title: option_into_v2_maybe_undefined(title)?,
2547            content: option_vec_into_v2_maybe_undefined_skip_errors(content),
2548            locations: option_vec_into_v2_maybe_undefined_skip_errors(locations),
2549            raw_input: option_into_v2_maybe_undefined(raw_input)?,
2550            raw_output: option_into_v2_maybe_undefined(raw_output)?,
2551            meta: option_into_v2_maybe_undefined(meta)?,
2552        })
2553    }
2554}
2555
2556impl IntoV1 for super::ToolCallId {
2557    type Output = crate::v1::ToolCallId;
2558
2559    fn into_v1(self) -> Result<Self::Output> {
2560        Ok(crate::v1::ToolCallId(self.0.into_v1()?))
2561    }
2562}
2563
2564impl IntoV2 for crate::v1::ToolCallId {
2565    type Output = super::ToolCallId;
2566
2567    fn into_v2(self) -> Result<Self::Output> {
2568        Ok(super::ToolCallId(self.0.into_v2()?))
2569    }
2570}
2571
2572impl IntoV1 for super::ToolKind {
2573    type Output = crate::v1::ToolKind;
2574
2575    fn into_v1(self) -> Result<Self::Output> {
2576        Ok(match self {
2577            Self::Read => crate::v1::ToolKind::Read,
2578            Self::Edit => crate::v1::ToolKind::Edit,
2579            Self::Delete => crate::v1::ToolKind::Delete,
2580            Self::Move => crate::v1::ToolKind::Move,
2581            Self::Search => crate::v1::ToolKind::Search,
2582            Self::Execute => crate::v1::ToolKind::Execute,
2583            Self::Think => crate::v1::ToolKind::Think,
2584            Self::Fetch => crate::v1::ToolKind::Fetch,
2585            Self::SwitchMode => crate::v1::ToolKind::SwitchMode,
2586            Self::Other => crate::v1::ToolKind::Other,
2587            Self::Unknown(value) => return Err(unknown_v2_enum_variant("ToolKind", &value)),
2588        })
2589    }
2590}
2591
2592impl IntoV2 for crate::v1::ToolKind {
2593    type Output = super::ToolKind;
2594
2595    fn into_v2(self) -> Result<Self::Output> {
2596        Ok(match self {
2597            Self::Read => super::ToolKind::Read,
2598            Self::Edit => super::ToolKind::Edit,
2599            Self::Delete => super::ToolKind::Delete,
2600            Self::Move => super::ToolKind::Move,
2601            Self::Search => super::ToolKind::Search,
2602            Self::Execute => super::ToolKind::Execute,
2603            Self::Think => super::ToolKind::Think,
2604            Self::Fetch => super::ToolKind::Fetch,
2605            Self::SwitchMode => super::ToolKind::SwitchMode,
2606            Self::Other => super::ToolKind::Other,
2607        })
2608    }
2609}
2610
2611impl IntoV1 for super::ToolCallStatus {
2612    type Output = crate::v1::ToolCallStatus;
2613
2614    fn into_v1(self) -> Result<Self::Output> {
2615        Ok(match self {
2616            Self::Pending => crate::v1::ToolCallStatus::Pending,
2617            Self::InProgress => crate::v1::ToolCallStatus::InProgress,
2618            Self::Completed => crate::v1::ToolCallStatus::Completed,
2619            Self::Failed => crate::v1::ToolCallStatus::Failed,
2620            Self::Other(value) => return Err(unknown_v2_enum_variant("ToolCallStatus", &value)),
2621        })
2622    }
2623}
2624
2625impl IntoV2 for crate::v1::ToolCallStatus {
2626    type Output = super::ToolCallStatus;
2627
2628    fn into_v2(self) -> Result<Self::Output> {
2629        Ok(match self {
2630            Self::Pending => super::ToolCallStatus::Pending,
2631            Self::InProgress => super::ToolCallStatus::InProgress,
2632            Self::Completed => super::ToolCallStatus::Completed,
2633            Self::Failed => super::ToolCallStatus::Failed,
2634        })
2635    }
2636}
2637
2638impl IntoV1 for super::ToolCallContent {
2639    type Output = crate::v1::ToolCallContent;
2640
2641    fn into_v1(self) -> Result<Self::Output> {
2642        Ok(match self {
2643            Self::Content(value) => crate::v1::ToolCallContent::Content(value.into_v1()?),
2644            Self::Diff(value) => crate::v1::ToolCallContent::Diff(value.into_v1()?),
2645            Self::Other(value) => {
2646                return Err(unknown_v2_enum_variant("ToolCallContent", &value.type_));
2647            }
2648        })
2649    }
2650}
2651
2652impl IntoV2 for crate::v1::ToolCallContent {
2653    type Output = super::ToolCallContent;
2654
2655    fn into_v2(self) -> Result<Self::Output> {
2656        Ok(match self {
2657            Self::Content(value) => super::ToolCallContent::Content(Box::new(value.into_v2()?)),
2658            Self::Diff(value) => super::ToolCallContent::Diff(value.into_v2()?),
2659            Self::Terminal(_) => {
2660                return Err(removed_v1_enum_variant("ToolCallContent", "terminal"));
2661            }
2662        })
2663    }
2664}
2665
2666impl IntoV1 for super::Content {
2667    type Output = crate::v1::Content;
2668
2669    fn into_v1(self) -> Result<Self::Output> {
2670        let Self { content, meta } = self;
2671        Ok(crate::v1::Content {
2672            content: content.into_v1()?,
2673            meta: meta.into_v1()?,
2674        })
2675    }
2676}
2677
2678impl IntoV2 for crate::v1::Content {
2679    type Output = super::Content;
2680
2681    fn into_v2(self) -> Result<Self::Output> {
2682        let Self { content, meta } = self;
2683        Ok(super::Content {
2684            content: content.into_v2()?,
2685            meta: meta.into_v2()?,
2686        })
2687    }
2688}
2689
2690impl IntoV1 for super::Diff {
2691    type Output = crate::v1::Diff;
2692
2693    fn into_v1(self) -> Result<Self::Output> {
2694        Err(ProtocolConversionError::new(
2695            "v2 Diff cannot be represented in v1 because v1 requires oldText/newText while v2 carries standard patch text and structured changes",
2696        ))
2697    }
2698}
2699
2700impl IntoV2 for crate::v1::Diff {
2701    type Output = super::Diff;
2702
2703    fn into_v2(self) -> Result<Self::Output> {
2704        let Self {
2705            path,
2706            old_text,
2707            new_text,
2708            meta,
2709        } = self;
2710        let path = path.into_v2()?;
2711        let old_text = old_text.into_v2()?;
2712        let new_text = new_text.into_v2()?;
2713        let change = if old_text.is_some() {
2714            super::DiffChange::modify(path.clone()).file_type(super::DiffFileType::Text)
2715        } else {
2716            super::DiffChange::add(path.clone()).file_type(super::DiffFileType::Text)
2717        };
2718        let diff = full_file_git_patch(&path, old_text.as_deref(), &new_text);
2719
2720        Ok(super::Diff::patch(diff, vec![change]).meta(meta.into_v2()?))
2721    }
2722}
2723
2724fn full_file_git_patch(path: &Path, old_text: Option<&str>, new_text: &str) -> String {
2725    let path = path.to_string_lossy();
2726    let old = old_text.unwrap_or_default();
2727    let original_filename = if old_text.is_some() {
2728        path.to_string()
2729    } else {
2730        "/dev/null".to_string()
2731    };
2732
2733    let mut options = diffy::DiffOptions::new();
2734    options
2735        .set_original_filename(original_filename)
2736        .set_modified_filename(path.to_string());
2737
2738    let mut diff = format!("diff --git {path} {path}\n");
2739    if old_text.is_none() {
2740        diff.push_str("new file mode 100644\n");
2741    }
2742    diff.push_str(&options.create_patch(old, new_text).to_string());
2743    diff
2744}
2745
2746impl IntoV1 for super::ToolCallLocation {
2747    type Output = crate::v1::ToolCallLocation;
2748
2749    fn into_v1(self) -> Result<Self::Output> {
2750        let Self { path, line, meta } = self;
2751        Ok(crate::v1::ToolCallLocation {
2752            path: path.into_v1()?,
2753            line: line.into_v1()?,
2754            meta: meta.into_v1()?,
2755        })
2756    }
2757}
2758
2759impl IntoV2 for crate::v1::ToolCallLocation {
2760    type Output = super::ToolCallLocation;
2761
2762    fn into_v2(self) -> Result<Self::Output> {
2763        let Self { path, line, meta } = self;
2764        Ok(super::ToolCallLocation {
2765            path: path.into_v2()?,
2766            line: line.into_v2()?,
2767            meta: meta.into_v2()?,
2768        })
2769    }
2770}
2771
2772impl IntoV1 for super::InitializeRequest {
2773    type Output = crate::v1::InitializeRequest;
2774
2775    fn into_v1(self) -> Result<Self::Output> {
2776        let Self {
2777            protocol_version,
2778            capabilities,
2779            info,
2780            meta,
2781        } = self;
2782        Ok(crate::v1::InitializeRequest {
2783            protocol_version: protocol_version.into_v1()?,
2784            client_capabilities: capabilities.into_v1()?,
2785            client_info: Some(info.into_v1()?),
2786            meta: meta.into_v1()?,
2787        })
2788    }
2789}
2790
2791impl IntoV2 for crate::v1::InitializeRequest {
2792    type Output = super::InitializeRequest;
2793
2794    fn into_v2(self) -> Result<Self::Output> {
2795        let Self {
2796            protocol_version,
2797            client_capabilities,
2798            client_info,
2799            meta,
2800        } = self;
2801        let info = match client_info {
2802            Some(client_info) => client_info.into_v2()?,
2803            None => {
2804                return Err(ProtocolConversionError::new(
2805                    "v1 InitializeRequest without `clientInfo` cannot be represented in v2",
2806                ));
2807            }
2808        };
2809        Ok(super::InitializeRequest {
2810            protocol_version: protocol_version.into_v2()?,
2811            capabilities: client_capabilities.into_v2()?,
2812            info,
2813            meta: meta.into_v2()?,
2814        })
2815    }
2816}
2817
2818impl IntoV1 for super::InitializeResponse {
2819    type Output = crate::v1::InitializeResponse;
2820
2821    fn into_v1(self) -> Result<Self::Output> {
2822        let Self {
2823            protocol_version,
2824            capabilities: agent_capabilities,
2825            auth_methods,
2826            info,
2827            meta,
2828        } = self;
2829        Ok(crate::v1::InitializeResponse {
2830            protocol_version: protocol_version.into_v1()?,
2831            agent_capabilities: agent_capabilities.into_v1()?,
2832            auth_methods: into_v1_vec_skip_errors(auth_methods),
2833            agent_info: Some(info.into_v1()?),
2834            meta: meta.into_v1()?,
2835        })
2836    }
2837}
2838
2839impl IntoV2 for crate::v1::InitializeResponse {
2840    type Output = super::InitializeResponse;
2841
2842    fn into_v2(self) -> Result<Self::Output> {
2843        let Self {
2844            protocol_version,
2845            agent_capabilities,
2846            auth_methods,
2847            agent_info,
2848            meta,
2849        } = self;
2850        let info = match agent_info {
2851            Some(agent_info) => agent_info.into_v2()?,
2852            None => {
2853                return Err(ProtocolConversionError::new(
2854                    "v1 InitializeResponse without `agentInfo` cannot be represented in v2",
2855                ));
2856            }
2857        };
2858        Ok(super::InitializeResponse {
2859            protocol_version: protocol_version.into_v2()?,
2860            capabilities: agent_capabilities.into_v2()?,
2861            auth_methods: into_v2_vec_skip_errors(auth_methods),
2862            info,
2863            meta: meta.into_v2()?,
2864        })
2865    }
2866}
2867
2868impl IntoV1 for super::Implementation {
2869    type Output = crate::v1::Implementation;
2870
2871    fn into_v1(self) -> Result<Self::Output> {
2872        let Self {
2873            name,
2874            title,
2875            version,
2876            meta,
2877        } = self;
2878        Ok(crate::v1::Implementation {
2879            name: name.into_v1()?,
2880            title: title.into_v1()?,
2881            version: version.into_v1()?,
2882            meta: meta.into_v1()?,
2883        })
2884    }
2885}
2886
2887impl IntoV2 for crate::v1::Implementation {
2888    type Output = super::Implementation;
2889
2890    fn into_v2(self) -> Result<Self::Output> {
2891        let Self {
2892            name,
2893            title,
2894            version,
2895            meta,
2896        } = self;
2897        Ok(super::Implementation {
2898            name: name.into_v2()?,
2899            title: title.into_v2()?,
2900            version: version.into_v2()?,
2901            meta: meta.into_v2()?,
2902        })
2903    }
2904}
2905
2906impl IntoV1 for super::LoginAuthRequest {
2907    type Output = crate::v1::AuthenticateRequest;
2908
2909    fn into_v1(self) -> Result<Self::Output> {
2910        let Self { method_id, meta } = self;
2911        Ok(crate::v1::AuthenticateRequest {
2912            method_id: method_id.into_v1()?,
2913            meta: meta.into_v1()?,
2914        })
2915    }
2916}
2917
2918impl IntoV2 for crate::v1::AuthenticateRequest {
2919    type Output = super::LoginAuthRequest;
2920
2921    fn into_v2(self) -> Result<Self::Output> {
2922        let Self { method_id, meta } = self;
2923        Ok(super::LoginAuthRequest {
2924            method_id: method_id.into_v2()?,
2925            meta: meta.into_v2()?,
2926        })
2927    }
2928}
2929
2930impl IntoV1 for super::LoginAuthResponse {
2931    type Output = crate::v1::AuthenticateResponse;
2932
2933    fn into_v1(self) -> Result<Self::Output> {
2934        let Self { meta } = self;
2935        Ok(crate::v1::AuthenticateResponse {
2936            meta: meta.into_v1()?,
2937        })
2938    }
2939}
2940
2941impl IntoV2 for crate::v1::AuthenticateResponse {
2942    type Output = super::LoginAuthResponse;
2943
2944    fn into_v2(self) -> Result<Self::Output> {
2945        let Self { meta } = self;
2946        Ok(super::LoginAuthResponse {
2947            meta: meta.into_v2()?,
2948        })
2949    }
2950}
2951
2952impl IntoV1 for super::LogoutAuthRequest {
2953    type Output = crate::v1::LogoutRequest;
2954
2955    fn into_v1(self) -> Result<Self::Output> {
2956        let Self { meta } = self;
2957        Ok(crate::v1::LogoutRequest {
2958            meta: meta.into_v1()?,
2959        })
2960    }
2961}
2962
2963impl IntoV2 for crate::v1::LogoutRequest {
2964    type Output = super::LogoutAuthRequest;
2965
2966    fn into_v2(self) -> Result<Self::Output> {
2967        let Self { meta } = self;
2968        Ok(super::LogoutAuthRequest {
2969            meta: meta.into_v2()?,
2970        })
2971    }
2972}
2973
2974impl IntoV1 for super::LogoutAuthResponse {
2975    type Output = crate::v1::LogoutResponse;
2976
2977    fn into_v1(self) -> Result<Self::Output> {
2978        let Self { meta } = self;
2979        Ok(crate::v1::LogoutResponse {
2980            meta: meta.into_v1()?,
2981        })
2982    }
2983}
2984
2985impl IntoV2 for crate::v1::LogoutResponse {
2986    type Output = super::LogoutAuthResponse;
2987
2988    fn into_v2(self) -> Result<Self::Output> {
2989        let Self { meta } = self;
2990        Ok(super::LogoutAuthResponse {
2991            meta: meta.into_v2()?,
2992        })
2993    }
2994}
2995
2996impl IntoV1 for super::AgentAuthCapabilities {
2997    type Output = crate::v1::AgentAuthCapabilities;
2998
2999    fn into_v1(self) -> Result<Self::Output> {
3000        let Self { meta } = self;
3001        Ok(crate::v1::AgentAuthCapabilities {
3002            logout: Some(crate::v1::LogoutCapabilities::new()),
3003            meta: meta.into_v1()?,
3004        })
3005    }
3006}
3007
3008impl IntoV2 for crate::v1::AgentAuthCapabilities {
3009    type Output = super::AgentAuthCapabilities;
3010
3011    fn into_v2(self) -> Result<Self::Output> {
3012        let Self { logout: _, meta } = self;
3013        Ok(super::AgentAuthCapabilities {
3014            meta: meta.into_v2()?,
3015        })
3016    }
3017}
3018
3019impl IntoV1 for super::AuthMethodId {
3020    type Output = crate::v1::AuthMethodId;
3021
3022    fn into_v1(self) -> Result<Self::Output> {
3023        Ok(crate::v1::AuthMethodId(self.0.into_v1()?))
3024    }
3025}
3026
3027impl IntoV2 for crate::v1::AuthMethodId {
3028    type Output = super::AuthMethodId;
3029
3030    fn into_v2(self) -> Result<Self::Output> {
3031        Ok(super::AuthMethodId(self.0.into_v2()?))
3032    }
3033}
3034
3035impl IntoV1 for super::AuthMethod {
3036    type Output = crate::v1::AuthMethod;
3037
3038    fn into_v1(self) -> Result<Self::Output> {
3039        Ok(match self {
3040            #[cfg(feature = "unstable_auth_methods")]
3041            Self::EnvVar(value) => crate::v1::AuthMethod::EnvVar(value.into_v1()?),
3042            #[cfg(feature = "unstable_auth_methods")]
3043            Self::Terminal(value) => crate::v1::AuthMethod::Terminal(value.into_v1()?),
3044            Self::Other(value) => {
3045                return Err(unknown_v2_enum_variant("AuthMethod", &value.type_));
3046            }
3047            Self::Agent(value) => crate::v1::AuthMethod::Agent(value.into_v1()?),
3048        })
3049    }
3050}
3051
3052impl IntoV2 for crate::v1::AuthMethod {
3053    type Output = super::AuthMethod;
3054
3055    fn into_v2(self) -> Result<Self::Output> {
3056        Ok(match self {
3057            #[cfg(feature = "unstable_auth_methods")]
3058            Self::EnvVar(value) => super::AuthMethod::EnvVar(value.into_v2()?),
3059            #[cfg(feature = "unstable_auth_methods")]
3060            Self::Terminal(value) => super::AuthMethod::Terminal(value.into_v2()?),
3061            Self::Agent(value) => super::AuthMethod::Agent(value.into_v2()?),
3062        })
3063    }
3064}
3065
3066impl IntoV1 for super::AuthMethodAgent {
3067    type Output = crate::v1::AuthMethodAgent;
3068
3069    fn into_v1(self) -> Result<Self::Output> {
3070        let Self {
3071            method_id,
3072            name,
3073            description,
3074            meta,
3075        } = self;
3076        Ok(crate::v1::AuthMethodAgent {
3077            id: method_id.into_v1()?,
3078            name: name.into_v1()?,
3079            description: description.into_v1()?,
3080            meta: meta.into_v1()?,
3081        })
3082    }
3083}
3084
3085impl IntoV2 for crate::v1::AuthMethodAgent {
3086    type Output = super::AuthMethodAgent;
3087
3088    fn into_v2(self) -> Result<Self::Output> {
3089        let Self {
3090            id,
3091            name,
3092            description,
3093            meta,
3094        } = self;
3095        Ok(super::AuthMethodAgent {
3096            method_id: id.into_v2()?,
3097            name: name.into_v2()?,
3098            description: description.into_v2()?,
3099            meta: meta.into_v2()?,
3100        })
3101    }
3102}
3103
3104#[cfg(feature = "unstable_auth_methods")]
3105impl IntoV1 for super::AuthMethodEnvVar {
3106    type Output = crate::v1::AuthMethodEnvVar;
3107
3108    fn into_v1(self) -> Result<Self::Output> {
3109        let Self {
3110            method_id,
3111            name,
3112            description,
3113            vars,
3114            link,
3115            meta,
3116        } = self;
3117        Ok(crate::v1::AuthMethodEnvVar {
3118            id: method_id.into_v1()?,
3119            name: name.into_v1()?,
3120            description: description.into_v1()?,
3121            vars: vars.into_v1()?,
3122            link: link.into_v1()?,
3123            meta: meta.into_v1()?,
3124        })
3125    }
3126}
3127
3128#[cfg(feature = "unstable_auth_methods")]
3129impl IntoV2 for crate::v1::AuthMethodEnvVar {
3130    type Output = super::AuthMethodEnvVar;
3131
3132    fn into_v2(self) -> Result<Self::Output> {
3133        let Self {
3134            id,
3135            name,
3136            description,
3137            vars,
3138            link,
3139            meta,
3140        } = self;
3141        Ok(super::AuthMethodEnvVar {
3142            method_id: id.into_v2()?,
3143            name: name.into_v2()?,
3144            description: description.into_v2()?,
3145            vars: vars.into_v2()?,
3146            link: link.into_v2()?,
3147            meta: meta.into_v2()?,
3148        })
3149    }
3150}
3151
3152#[cfg(feature = "unstable_auth_methods")]
3153impl IntoV1 for super::AuthEnvVar {
3154    type Output = crate::v1::AuthEnvVar;
3155
3156    fn into_v1(self) -> Result<Self::Output> {
3157        let Self {
3158            name,
3159            label,
3160            secret,
3161            optional,
3162            meta,
3163        } = self;
3164        Ok(crate::v1::AuthEnvVar {
3165            name: name.into_v1()?,
3166            label: label.into_v1()?,
3167            secret: secret.into_v1()?,
3168            optional: optional.into_v1()?,
3169            meta: meta.into_v1()?,
3170        })
3171    }
3172}
3173
3174#[cfg(feature = "unstable_auth_methods")]
3175impl IntoV2 for crate::v1::AuthEnvVar {
3176    type Output = super::AuthEnvVar;
3177
3178    fn into_v2(self) -> Result<Self::Output> {
3179        let Self {
3180            name,
3181            label,
3182            secret,
3183            optional,
3184            meta,
3185        } = self;
3186        Ok(super::AuthEnvVar {
3187            name: name.into_v2()?,
3188            label: label.into_v2()?,
3189            secret: secret.into_v2()?,
3190            optional: optional.into_v2()?,
3191            meta: meta.into_v2()?,
3192        })
3193    }
3194}
3195
3196#[cfg(feature = "unstable_auth_methods")]
3197impl IntoV1 for super::AuthMethodTerminal {
3198    type Output = crate::v1::AuthMethodTerminal;
3199
3200    fn into_v1(self) -> Result<Self::Output> {
3201        let Self {
3202            method_id,
3203            name,
3204            description,
3205            args,
3206            env,
3207            meta,
3208        } = self;
3209        let env = env
3210            .into_iter()
3211            .map(|env_var| {
3212                let super::EnvVariable { name, value, meta } = env_var;
3213                if meta.is_some() {
3214                    return Err(ProtocolConversionError::new(
3215                        "v2 AuthMethodTerminal env variable `_meta` cannot be represented in v1",
3216                    ));
3217                }
3218                Ok((name.into_v1()?, value.into_v1()?))
3219            })
3220            .try_fold(HashMap::new(), |mut env, item| {
3221                let (name, value) = item?;
3222                if env.insert(name.clone(), value).is_some() {
3223                    return Err(ProtocolConversionError::new(format!(
3224                        "v2 AuthMethodTerminal env variable `{name}` is duplicated and cannot be represented in v1",
3225                    )));
3226                }
3227                Ok(env)
3228            })?;
3229        Ok(crate::v1::AuthMethodTerminal {
3230            id: method_id.into_v1()?,
3231            name: name.into_v1()?,
3232            description: description.into_v1()?,
3233            args: args.into_v1()?,
3234            env,
3235            meta: meta.into_v1()?,
3236        })
3237    }
3238}
3239
3240#[cfg(feature = "unstable_auth_methods")]
3241impl IntoV2 for crate::v1::AuthMethodTerminal {
3242    type Output = super::AuthMethodTerminal;
3243
3244    fn into_v2(self) -> Result<Self::Output> {
3245        let Self {
3246            id,
3247            name,
3248            description,
3249            args,
3250            env,
3251            meta,
3252        } = self;
3253        let mut env = env
3254            .into_iter()
3255            .map(|(name, value)| Ok(super::EnvVariable::new(name.into_v2()?, value.into_v2()?)))
3256            .collect::<Result<Vec<_>>>()?;
3257        env.sort_by(|left, right| left.name.cmp(&right.name));
3258        Ok(super::AuthMethodTerminal {
3259            method_id: id.into_v2()?,
3260            name: name.into_v2()?,
3261            description: description.into_v2()?,
3262            args: args.into_v2()?,
3263            env,
3264            meta: meta.into_v2()?,
3265        })
3266    }
3267}
3268
3269impl IntoV1 for super::NewSessionRequest {
3270    type Output = crate::v1::NewSessionRequest;
3271
3272    fn into_v1(self) -> Result<Self::Output> {
3273        let Self {
3274            cwd,
3275            additional_directories,
3276            mcp_servers,
3277            meta,
3278        } = self;
3279        Ok(crate::v1::NewSessionRequest {
3280            cwd: cwd.into_v1()?,
3281            additional_directories: additional_directories.into_v1()?,
3282            mcp_servers: mcp_servers.into_v1()?,
3283            meta: meta.into_v1()?,
3284        })
3285    }
3286}
3287
3288impl IntoV2 for crate::v1::NewSessionRequest {
3289    type Output = super::NewSessionRequest;
3290
3291    fn into_v2(self) -> Result<Self::Output> {
3292        let Self {
3293            cwd,
3294            additional_directories,
3295            mcp_servers,
3296            meta,
3297        } = self;
3298        Ok(super::NewSessionRequest {
3299            cwd: cwd.into_v2()?,
3300            additional_directories: additional_directories.into_v2()?,
3301            mcp_servers: mcp_servers.into_v2()?,
3302            meta: meta.into_v2()?,
3303        })
3304    }
3305}
3306
3307impl IntoV1 for super::NewSessionResponse {
3308    type Output = crate::v1::NewSessionResponse;
3309
3310    fn into_v1(self) -> Result<Self::Output> {
3311        let Self {
3312            session_id,
3313            config_options,
3314            meta,
3315        } = self;
3316        Ok(crate::v1::NewSessionResponse {
3317            session_id: session_id.into_v1()?,
3318            modes: None,
3319            config_options: Some(into_v1_vec_skip_errors(config_options)),
3320            meta: meta.into_v1()?,
3321        })
3322    }
3323}
3324
3325impl IntoV2 for crate::v1::NewSessionResponse {
3326    type Output = super::NewSessionResponse;
3327
3328    fn into_v2(self) -> Result<Self::Output> {
3329        let Self {
3330            session_id,
3331            modes: _,
3332            config_options,
3333            meta,
3334        } = self;
3335        Ok(super::NewSessionResponse {
3336            session_id: session_id.into_v2()?,
3337            config_options: option_vec_into_v2_default_skip_errors(config_options),
3338            meta: meta.into_v2()?,
3339        })
3340    }
3341}
3342
3343impl IntoV2 for crate::v1::LoadSessionRequest {
3344    type Output = super::ResumeSessionRequest;
3345
3346    fn into_v2(self) -> Result<Self::Output> {
3347        let Self {
3348            mcp_servers,
3349            cwd,
3350            additional_directories,
3351            session_id,
3352            meta,
3353        } = self;
3354        Ok(super::ResumeSessionRequest {
3355            mcp_servers: mcp_servers.into_v2()?,
3356            cwd: cwd.into_v2()?,
3357            additional_directories: additional_directories.into_v2()?,
3358            session_id: session_id.into_v2()?,
3359            replay_from: Some(super::ReplayFrom::Start(super::ReplayFromStart::new())),
3360            meta: meta.into_v2()?,
3361        })
3362    }
3363}
3364
3365impl IntoV2 for crate::v1::LoadSessionResponse {
3366    type Output = super::ResumeSessionResponse;
3367
3368    fn into_v2(self) -> Result<Self::Output> {
3369        let Self {
3370            modes: _,
3371            config_options,
3372            meta,
3373        } = self;
3374        Ok(super::ResumeSessionResponse {
3375            config_options: option_vec_into_v2_default_skip_errors(config_options),
3376            meta: meta.into_v2()?,
3377        })
3378    }
3379}
3380
3381fn v2_resume_session_request_into_v1_load(
3382    request: super::ResumeSessionRequest,
3383) -> Result<crate::v1::LoadSessionRequest> {
3384    let super::ResumeSessionRequest {
3385        session_id,
3386        cwd,
3387        additional_directories,
3388        mcp_servers,
3389        replay_from: _,
3390        meta,
3391    } = request;
3392    Ok(crate::v1::LoadSessionRequest {
3393        mcp_servers: mcp_servers.into_v1()?,
3394        cwd: cwd.into_v1()?,
3395        additional_directories: additional_directories.into_v1()?,
3396        session_id: session_id.into_v1()?,
3397        meta: meta.into_v1()?,
3398    })
3399}
3400
3401fn unsupported_replay_from_for_v1_resume(
3402    replay_from: super::ReplayFrom,
3403) -> ProtocolConversionError {
3404    match replay_from {
3405        super::ReplayFrom::Start(_) => ProtocolConversionError::new(
3406            "v2 ResumeSessionRequest `replayFrom: start` maps to v1 session/load, not v1 session/resume",
3407        ),
3408        super::ReplayFrom::Other(other) => unknown_v2_enum_variant("ReplayFrom", &other.type_),
3409    }
3410}
3411
3412fn v2_resume_session_request_into_v1_client_request(
3413    request: super::ResumeSessionRequest,
3414) -> Result<crate::v1::ClientRequest> {
3415    match request.replay_from.clone() {
3416        None => Ok(crate::v1::ClientRequest::ResumeSessionRequest(
3417            request.into_v1()?,
3418        )),
3419        Some(super::ReplayFrom::Start(_)) => Ok(crate::v1::ClientRequest::LoadSessionRequest(
3420            v2_resume_session_request_into_v1_load(request)?,
3421        )),
3422        Some(super::ReplayFrom::Other(other)) => {
3423            Err(unknown_v2_enum_variant("ReplayFrom", &other.type_))
3424        }
3425    }
3426}
3427
3428#[cfg(feature = "unstable_session_fork")]
3429impl IntoV1 for super::ForkSessionRequest {
3430    type Output = crate::v1::ForkSessionRequest;
3431
3432    fn into_v1(self) -> Result<Self::Output> {
3433        let Self {
3434            session_id,
3435            cwd,
3436            additional_directories,
3437            mcp_servers,
3438            meta,
3439        } = self;
3440        Ok(crate::v1::ForkSessionRequest {
3441            session_id: session_id.into_v1()?,
3442            cwd: cwd.into_v1()?,
3443            additional_directories: additional_directories.into_v1()?,
3444            mcp_servers: mcp_servers.into_v1()?,
3445            meta: meta.into_v1()?,
3446        })
3447    }
3448}
3449
3450#[cfg(feature = "unstable_session_fork")]
3451impl IntoV2 for crate::v1::ForkSessionRequest {
3452    type Output = super::ForkSessionRequest;
3453
3454    fn into_v2(self) -> Result<Self::Output> {
3455        let Self {
3456            session_id,
3457            cwd,
3458            additional_directories,
3459            mcp_servers,
3460            meta,
3461        } = self;
3462        Ok(super::ForkSessionRequest {
3463            session_id: session_id.into_v2()?,
3464            cwd: cwd.into_v2()?,
3465            additional_directories: additional_directories.into_v2()?,
3466            mcp_servers: mcp_servers.into_v2()?,
3467            meta: meta.into_v2()?,
3468        })
3469    }
3470}
3471
3472#[cfg(feature = "unstable_session_fork")]
3473impl IntoV1 for super::ForkSessionResponse {
3474    type Output = crate::v1::ForkSessionResponse;
3475
3476    fn into_v1(self) -> Result<Self::Output> {
3477        let Self {
3478            session_id,
3479            config_options,
3480            meta,
3481        } = self;
3482        Ok(crate::v1::ForkSessionResponse {
3483            session_id: session_id.into_v1()?,
3484            modes: None,
3485            config_options: Some(into_v1_vec_skip_errors(config_options)),
3486            meta: meta.into_v1()?,
3487        })
3488    }
3489}
3490
3491#[cfg(feature = "unstable_session_fork")]
3492impl IntoV2 for crate::v1::ForkSessionResponse {
3493    type Output = super::ForkSessionResponse;
3494
3495    fn into_v2(self) -> Result<Self::Output> {
3496        let Self {
3497            session_id,
3498            modes: _,
3499            config_options,
3500            meta,
3501        } = self;
3502        Ok(super::ForkSessionResponse {
3503            session_id: session_id.into_v2()?,
3504            config_options: option_vec_into_v2_default_skip_errors(config_options),
3505            meta: meta.into_v2()?,
3506        })
3507    }
3508}
3509
3510impl IntoV1 for super::ResumeSessionRequest {
3511    type Output = crate::v1::ResumeSessionRequest;
3512
3513    fn into_v1(self) -> Result<Self::Output> {
3514        let Self {
3515            session_id,
3516            cwd,
3517            additional_directories,
3518            mcp_servers,
3519            replay_from,
3520            meta,
3521        } = self;
3522        if let Some(replay_from) = replay_from {
3523            return Err(unsupported_replay_from_for_v1_resume(replay_from));
3524        }
3525        Ok(crate::v1::ResumeSessionRequest {
3526            session_id: session_id.into_v1()?,
3527            cwd: cwd.into_v1()?,
3528            additional_directories: additional_directories.into_v1()?,
3529            mcp_servers: mcp_servers.into_v1()?,
3530            meta: meta.into_v1()?,
3531        })
3532    }
3533}
3534
3535impl IntoV2 for crate::v1::ResumeSessionRequest {
3536    type Output = super::ResumeSessionRequest;
3537
3538    fn into_v2(self) -> Result<Self::Output> {
3539        let Self {
3540            session_id,
3541            cwd,
3542            additional_directories,
3543            mcp_servers,
3544            meta,
3545        } = self;
3546        Ok(super::ResumeSessionRequest {
3547            session_id: session_id.into_v2()?,
3548            cwd: cwd.into_v2()?,
3549            additional_directories: additional_directories.into_v2()?,
3550            mcp_servers: mcp_servers.into_v2()?,
3551            replay_from: None,
3552            meta: meta.into_v2()?,
3553        })
3554    }
3555}
3556
3557impl IntoV1 for super::ResumeSessionResponse {
3558    type Output = crate::v1::ResumeSessionResponse;
3559
3560    fn into_v1(self) -> Result<Self::Output> {
3561        let Self {
3562            config_options,
3563            meta,
3564        } = self;
3565        Ok(crate::v1::ResumeSessionResponse {
3566            modes: None,
3567            config_options: Some(into_v1_vec_skip_errors(config_options)),
3568            meta: meta.into_v1()?,
3569        })
3570    }
3571}
3572
3573impl IntoV2 for crate::v1::ResumeSessionResponse {
3574    type Output = super::ResumeSessionResponse;
3575
3576    fn into_v2(self) -> Result<Self::Output> {
3577        let Self {
3578            modes: _,
3579            config_options,
3580            meta,
3581        } = self;
3582        Ok(super::ResumeSessionResponse {
3583            config_options: option_vec_into_v2_default_skip_errors(config_options),
3584            meta: meta.into_v2()?,
3585        })
3586    }
3587}
3588
3589impl IntoV1 for super::CloseSessionRequest {
3590    type Output = crate::v1::CloseSessionRequest;
3591
3592    fn into_v1(self) -> Result<Self::Output> {
3593        let Self { session_id, meta } = self;
3594        Ok(crate::v1::CloseSessionRequest {
3595            session_id: session_id.into_v1()?,
3596            meta: meta.into_v1()?,
3597        })
3598    }
3599}
3600
3601impl IntoV2 for crate::v1::CloseSessionRequest {
3602    type Output = super::CloseSessionRequest;
3603
3604    fn into_v2(self) -> Result<Self::Output> {
3605        let Self { session_id, meta } = self;
3606        Ok(super::CloseSessionRequest {
3607            session_id: session_id.into_v2()?,
3608            meta: meta.into_v2()?,
3609        })
3610    }
3611}
3612
3613impl IntoV1 for super::CloseSessionResponse {
3614    type Output = crate::v1::CloseSessionResponse;
3615
3616    fn into_v1(self) -> Result<Self::Output> {
3617        let Self { meta } = self;
3618        Ok(crate::v1::CloseSessionResponse {
3619            meta: meta.into_v1()?,
3620        })
3621    }
3622}
3623
3624impl IntoV2 for crate::v1::CloseSessionResponse {
3625    type Output = super::CloseSessionResponse;
3626
3627    fn into_v2(self) -> Result<Self::Output> {
3628        let Self { meta } = self;
3629        Ok(super::CloseSessionResponse {
3630            meta: meta.into_v2()?,
3631        })
3632    }
3633}
3634
3635impl IntoV1 for super::DeleteSessionRequest {
3636    type Output = crate::v1::DeleteSessionRequest;
3637
3638    fn into_v1(self) -> Result<Self::Output> {
3639        let Self { session_id, meta } = self;
3640        Ok(crate::v1::DeleteSessionRequest {
3641            session_id: session_id.into_v1()?,
3642            meta: meta.into_v1()?,
3643        })
3644    }
3645}
3646
3647impl IntoV2 for crate::v1::DeleteSessionRequest {
3648    type Output = super::DeleteSessionRequest;
3649
3650    fn into_v2(self) -> Result<Self::Output> {
3651        let Self { session_id, meta } = self;
3652        Ok(super::DeleteSessionRequest {
3653            session_id: session_id.into_v2()?,
3654            meta: meta.into_v2()?,
3655        })
3656    }
3657}
3658
3659impl IntoV1 for super::DeleteSessionResponse {
3660    type Output = crate::v1::DeleteSessionResponse;
3661
3662    fn into_v1(self) -> Result<Self::Output> {
3663        let Self { meta } = self;
3664        Ok(crate::v1::DeleteSessionResponse {
3665            meta: meta.into_v1()?,
3666        })
3667    }
3668}
3669
3670impl IntoV2 for crate::v1::DeleteSessionResponse {
3671    type Output = super::DeleteSessionResponse;
3672
3673    fn into_v2(self) -> Result<Self::Output> {
3674        let Self { meta } = self;
3675        Ok(super::DeleteSessionResponse {
3676            meta: meta.into_v2()?,
3677        })
3678    }
3679}
3680
3681impl IntoV1 for super::ListSessionsRequest {
3682    type Output = crate::v1::ListSessionsRequest;
3683
3684    fn into_v1(self) -> Result<Self::Output> {
3685        let Self { cwd, cursor, meta } = self;
3686        Ok(crate::v1::ListSessionsRequest {
3687            cwd: cwd.into_v1()?,
3688            cursor: cursor.into_v1()?,
3689            meta: meta.into_v1()?,
3690        })
3691    }
3692}
3693
3694impl IntoV2 for crate::v1::ListSessionsRequest {
3695    type Output = super::ListSessionsRequest;
3696
3697    fn into_v2(self) -> Result<Self::Output> {
3698        let Self { cwd, cursor, meta } = self;
3699        Ok(super::ListSessionsRequest {
3700            cwd: cwd.into_v2()?,
3701            cursor: cursor.into_v2()?,
3702            meta: meta.into_v2()?,
3703        })
3704    }
3705}
3706
3707impl IntoV1 for super::ListSessionsResponse {
3708    type Output = crate::v1::ListSessionsResponse;
3709
3710    fn into_v1(self) -> Result<Self::Output> {
3711        let Self {
3712            sessions,
3713            next_cursor,
3714            meta,
3715        } = self;
3716        Ok(crate::v1::ListSessionsResponse {
3717            sessions: into_v1_vec_skip_errors(sessions),
3718            next_cursor: next_cursor.into_v1()?,
3719            meta: meta.into_v1()?,
3720        })
3721    }
3722}
3723
3724impl IntoV2 for crate::v1::ListSessionsResponse {
3725    type Output = super::ListSessionsResponse;
3726
3727    fn into_v2(self) -> Result<Self::Output> {
3728        let Self {
3729            sessions,
3730            next_cursor,
3731            meta,
3732        } = self;
3733        Ok(super::ListSessionsResponse {
3734            sessions: into_v2_vec_skip_errors(sessions),
3735            next_cursor: next_cursor.into_v2()?,
3736            meta: meta.into_v2()?,
3737        })
3738    }
3739}
3740
3741impl IntoV1 for super::SessionInfo {
3742    type Output = crate::v1::SessionInfo;
3743
3744    fn into_v1(self) -> Result<Self::Output> {
3745        let Self {
3746            session_id,
3747            cwd,
3748            additional_directories,
3749            title,
3750            updated_at,
3751            meta,
3752        } = self;
3753        Ok(crate::v1::SessionInfo {
3754            session_id: session_id.into_v1()?,
3755            cwd: cwd.into_v1()?,
3756            additional_directories: additional_directories.into_v1()?,
3757            title: into_v1_default_on_error(title),
3758            updated_at: into_v1_default_on_error(updated_at),
3759            meta: meta.into_v1()?,
3760        })
3761    }
3762}
3763
3764impl IntoV2 for crate::v1::SessionInfo {
3765    type Output = super::SessionInfo;
3766
3767    fn into_v2(self) -> Result<Self::Output> {
3768        let Self {
3769            session_id,
3770            cwd,
3771            additional_directories,
3772            title,
3773            updated_at,
3774            meta,
3775        } = self;
3776        Ok(super::SessionInfo {
3777            session_id: session_id.into_v2()?,
3778            cwd: cwd.into_v2()?,
3779            additional_directories: additional_directories.into_v2()?,
3780            title: into_v2_default_on_error(title),
3781            updated_at: into_v2_default_on_error(updated_at),
3782            meta: meta.into_v2()?,
3783        })
3784    }
3785}
3786
3787impl IntoV1 for super::SessionConfigId {
3788    type Output = crate::v1::SessionConfigId;
3789
3790    fn into_v1(self) -> Result<Self::Output> {
3791        Ok(crate::v1::SessionConfigId(self.0.into_v1()?))
3792    }
3793}
3794
3795impl IntoV2 for crate::v1::SessionConfigId {
3796    type Output = super::SessionConfigId;
3797
3798    fn into_v2(self) -> Result<Self::Output> {
3799        Ok(super::SessionConfigId(self.0.into_v2()?))
3800    }
3801}
3802
3803impl IntoV1 for super::SessionConfigValueId {
3804    type Output = crate::v1::SessionConfigValueId;
3805
3806    fn into_v1(self) -> Result<Self::Output> {
3807        Ok(crate::v1::SessionConfigValueId(self.0.into_v1()?))
3808    }
3809}
3810
3811impl IntoV2 for crate::v1::SessionConfigValueId {
3812    type Output = super::SessionConfigValueId;
3813
3814    fn into_v2(self) -> Result<Self::Output> {
3815        Ok(super::SessionConfigValueId(self.0.into_v2()?))
3816    }
3817}
3818
3819impl IntoV1 for super::SessionConfigGroupId {
3820    type Output = crate::v1::SessionConfigGroupId;
3821
3822    fn into_v1(self) -> Result<Self::Output> {
3823        Ok(crate::v1::SessionConfigGroupId(self.0.into_v1()?))
3824    }
3825}
3826
3827impl IntoV2 for crate::v1::SessionConfigGroupId {
3828    type Output = super::SessionConfigGroupId;
3829
3830    fn into_v2(self) -> Result<Self::Output> {
3831        Ok(super::SessionConfigGroupId(self.0.into_v2()?))
3832    }
3833}
3834
3835impl IntoV1 for super::SessionConfigSelectOption {
3836    type Output = crate::v1::SessionConfigSelectOption;
3837
3838    fn into_v1(self) -> Result<Self::Output> {
3839        let Self {
3840            value,
3841            name,
3842            description,
3843            meta,
3844        } = self;
3845        Ok(crate::v1::SessionConfigSelectOption {
3846            value: value.into_v1()?,
3847            name: name.into_v1()?,
3848            description: description.into_v1()?,
3849            meta: meta.into_v1()?,
3850        })
3851    }
3852}
3853
3854impl IntoV2 for crate::v1::SessionConfigSelectOption {
3855    type Output = super::SessionConfigSelectOption;
3856
3857    fn into_v2(self) -> Result<Self::Output> {
3858        let Self {
3859            value,
3860            name,
3861            description,
3862            meta,
3863        } = self;
3864        Ok(super::SessionConfigSelectOption {
3865            value: value.into_v2()?,
3866            name: name.into_v2()?,
3867            description: description.into_v2()?,
3868            meta: meta.into_v2()?,
3869        })
3870    }
3871}
3872
3873impl IntoV1 for super::SessionConfigSelectGroup {
3874    type Output = crate::v1::SessionConfigSelectGroup;
3875
3876    fn into_v1(self) -> Result<Self::Output> {
3877        let Self {
3878            group_id,
3879            name,
3880            options,
3881            meta,
3882        } = self;
3883        Ok(crate::v1::SessionConfigSelectGroup {
3884            group: group_id.into_v1()?,
3885            name: name.into_v1()?,
3886            options: options.into_v1()?,
3887            meta: meta.into_v1()?,
3888        })
3889    }
3890}
3891
3892impl IntoV2 for crate::v1::SessionConfigSelectGroup {
3893    type Output = super::SessionConfigSelectGroup;
3894
3895    fn into_v2(self) -> Result<Self::Output> {
3896        let Self {
3897            group,
3898            name,
3899            options,
3900            meta,
3901        } = self;
3902        Ok(super::SessionConfigSelectGroup {
3903            group_id: group.into_v2()?,
3904            name: name.into_v2()?,
3905            options: options.into_v2()?,
3906            meta: meta.into_v2()?,
3907        })
3908    }
3909}
3910
3911impl IntoV1 for super::SessionConfigSelectOptions {
3912    type Output = crate::v1::SessionConfigSelectOptions;
3913
3914    fn into_v1(self) -> Result<Self::Output> {
3915        Ok(match self {
3916            Self::Ungrouped(value) => {
3917                crate::v1::SessionConfigSelectOptions::Ungrouped(value.into_v1()?)
3918            }
3919            Self::Grouped(value) => {
3920                crate::v1::SessionConfigSelectOptions::Grouped(value.into_v1()?)
3921            }
3922        })
3923    }
3924}
3925
3926impl IntoV2 for crate::v1::SessionConfigSelectOptions {
3927    type Output = super::SessionConfigSelectOptions;
3928
3929    fn into_v2(self) -> Result<Self::Output> {
3930        Ok(match self {
3931            Self::Ungrouped(value) => {
3932                super::SessionConfigSelectOptions::Ungrouped(value.into_v2()?)
3933            }
3934            Self::Grouped(value) => super::SessionConfigSelectOptions::Grouped(value.into_v2()?),
3935        })
3936    }
3937}
3938
3939impl IntoV1 for super::SessionConfigSelect {
3940    type Output = crate::v1::SessionConfigSelect;
3941
3942    fn into_v1(self) -> Result<Self::Output> {
3943        let Self {
3944            current_value,
3945            options,
3946        } = self;
3947        Ok(crate::v1::SessionConfigSelect {
3948            current_value: current_value.into_v1()?,
3949            options: options.into_v1()?,
3950        })
3951    }
3952}
3953
3954impl IntoV2 for crate::v1::SessionConfigSelect {
3955    type Output = super::SessionConfigSelect;
3956
3957    fn into_v2(self) -> Result<Self::Output> {
3958        let Self {
3959            current_value,
3960            options,
3961        } = self;
3962        Ok(super::SessionConfigSelect {
3963            current_value: current_value.into_v2()?,
3964            options: options.into_v2()?,
3965        })
3966    }
3967}
3968
3969impl IntoV1 for super::SessionConfigBoolean {
3970    type Output = crate::v1::SessionConfigBoolean;
3971
3972    fn into_v1(self) -> Result<Self::Output> {
3973        let Self { current_value } = self;
3974        Ok(crate::v1::SessionConfigBoolean {
3975            current_value: current_value.into_v1()?,
3976        })
3977    }
3978}
3979
3980impl IntoV2 for crate::v1::SessionConfigBoolean {
3981    type Output = super::SessionConfigBoolean;
3982
3983    fn into_v2(self) -> Result<Self::Output> {
3984        let Self { current_value } = self;
3985        Ok(super::SessionConfigBoolean {
3986            current_value: current_value.into_v2()?,
3987        })
3988    }
3989}
3990
3991impl IntoV1 for super::SessionConfigOptionCategory {
3992    type Output = crate::v1::SessionConfigOptionCategory;
3993
3994    fn into_v1(self) -> Result<Self::Output> {
3995        Ok(match self {
3996            Self::Mode => crate::v1::SessionConfigOptionCategory::Mode,
3997            Self::Model => crate::v1::SessionConfigOptionCategory::Model,
3998            Self::ModelConfig => crate::v1::SessionConfigOptionCategory::ModelConfig,
3999            Self::ThoughtLevel => crate::v1::SessionConfigOptionCategory::ThoughtLevel,
4000            Self::Other(value) => crate::v1::SessionConfigOptionCategory::Other(value.into_v1()?),
4001        })
4002    }
4003}
4004
4005impl IntoV2 for crate::v1::SessionConfigOptionCategory {
4006    type Output = super::SessionConfigOptionCategory;
4007
4008    fn into_v2(self) -> Result<Self::Output> {
4009        Ok(match self {
4010            Self::Mode => super::SessionConfigOptionCategory::Mode,
4011            Self::Model => super::SessionConfigOptionCategory::Model,
4012            Self::ModelConfig => super::SessionConfigOptionCategory::ModelConfig,
4013            Self::ThoughtLevel => super::SessionConfigOptionCategory::ThoughtLevel,
4014            Self::Other(value) => super::SessionConfigOptionCategory::Other(value.into_v2()?),
4015        })
4016    }
4017}
4018
4019impl IntoV1 for super::SessionConfigKind {
4020    type Output = crate::v1::SessionConfigKind;
4021
4022    fn into_v1(self) -> Result<Self::Output> {
4023        Ok(match self {
4024            Self::Select(value) => crate::v1::SessionConfigKind::Select(value.into_v1()?),
4025            Self::Boolean(value) => crate::v1::SessionConfigKind::Boolean(value.into_v1()?),
4026            Self::Other(value) => {
4027                return Err(unknown_v2_enum_variant("SessionConfigKind", &value.type_));
4028            }
4029        })
4030    }
4031}
4032
4033impl IntoV2 for crate::v1::SessionConfigKind {
4034    type Output = super::SessionConfigKind;
4035
4036    fn into_v2(self) -> Result<Self::Output> {
4037        Ok(match self {
4038            Self::Select(value) => super::SessionConfigKind::Select(value.into_v2()?),
4039            Self::Boolean(value) => super::SessionConfigKind::Boolean(value.into_v2()?),
4040        })
4041    }
4042}
4043
4044impl IntoV1 for super::SessionConfigOption {
4045    type Output = crate::v1::SessionConfigOption;
4046
4047    fn into_v1(self) -> Result<Self::Output> {
4048        let Self {
4049            config_id,
4050            name,
4051            description,
4052            category,
4053            kind,
4054            meta,
4055        } = self;
4056        Ok(crate::v1::SessionConfigOption {
4057            id: config_id.into_v1()?,
4058            name: name.into_v1()?,
4059            description: description.into_v1()?,
4060            category: into_v1_default_on_error(category),
4061            kind: kind.into_v1()?,
4062            meta: meta.into_v1()?,
4063        })
4064    }
4065}
4066
4067impl IntoV2 for crate::v1::SessionConfigOption {
4068    type Output = super::SessionConfigOption;
4069
4070    fn into_v2(self) -> Result<Self::Output> {
4071        let Self {
4072            id,
4073            name,
4074            description,
4075            category,
4076            kind,
4077            meta,
4078        } = self;
4079        Ok(super::SessionConfigOption {
4080            config_id: id.into_v2()?,
4081            name: name.into_v2()?,
4082            description: description.into_v2()?,
4083            category: into_v2_default_on_error(category),
4084            kind: kind.into_v2()?,
4085            meta: meta.into_v2()?,
4086        })
4087    }
4088}
4089
4090impl IntoV1 for super::SessionConfigOptionValue {
4091    type Output = crate::v1::SessionConfigOptionValue;
4092
4093    fn into_v1(self) -> Result<Self::Output> {
4094        Ok(match self {
4095            Self::Id { value } => crate::v1::SessionConfigOptionValue::ValueId {
4096                value: value.into_v1()?,
4097            },
4098            Self::Boolean { value } => crate::v1::SessionConfigOptionValue::Boolean {
4099                value: value.into_v1()?,
4100            },
4101            Self::Other(value) => {
4102                return Err(unknown_v2_enum_variant(
4103                    "SessionConfigOptionValue",
4104                    &value.type_,
4105                ));
4106            }
4107        })
4108    }
4109}
4110
4111impl IntoV2 for crate::v1::SessionConfigOptionValue {
4112    type Output = super::SessionConfigOptionValue;
4113
4114    fn into_v2(self) -> Result<Self::Output> {
4115        Ok(match self {
4116            Self::Boolean { value } => super::SessionConfigOptionValue::Boolean {
4117                value: value.into_v2()?,
4118            },
4119            Self::ValueId { value } => super::SessionConfigOptionValue::Id {
4120                value: value.into_v2()?,
4121            },
4122        })
4123    }
4124}
4125
4126impl IntoV1 for super::SetSessionConfigOptionRequest {
4127    type Output = crate::v1::SetSessionConfigOptionRequest;
4128
4129    fn into_v1(self) -> Result<Self::Output> {
4130        let Self {
4131            session_id,
4132            config_id,
4133            value,
4134            meta,
4135        } = self;
4136        Ok(crate::v1::SetSessionConfigOptionRequest {
4137            session_id: session_id.into_v1()?,
4138            config_id: config_id.into_v1()?,
4139            value: value.into_v1()?,
4140            meta: meta.into_v1()?,
4141        })
4142    }
4143}
4144
4145impl IntoV2 for crate::v1::SetSessionConfigOptionRequest {
4146    type Output = super::SetSessionConfigOptionRequest;
4147
4148    fn into_v2(self) -> Result<Self::Output> {
4149        let Self {
4150            session_id,
4151            config_id,
4152            value,
4153            meta,
4154        } = self;
4155        Ok(super::SetSessionConfigOptionRequest {
4156            session_id: session_id.into_v2()?,
4157            config_id: config_id.into_v2()?,
4158            value: value.into_v2()?,
4159            meta: meta.into_v2()?,
4160        })
4161    }
4162}
4163
4164impl IntoV1 for super::SetSessionConfigOptionResponse {
4165    type Output = crate::v1::SetSessionConfigOptionResponse;
4166
4167    fn into_v1(self) -> Result<Self::Output> {
4168        let Self {
4169            config_options,
4170            meta,
4171        } = self;
4172        Ok(crate::v1::SetSessionConfigOptionResponse {
4173            config_options: into_v1_vec_skip_errors(config_options),
4174            meta: meta.into_v1()?,
4175        })
4176    }
4177}
4178
4179impl IntoV2 for crate::v1::SetSessionConfigOptionResponse {
4180    type Output = super::SetSessionConfigOptionResponse;
4181
4182    fn into_v2(self) -> Result<Self::Output> {
4183        let Self {
4184            config_options,
4185            meta,
4186        } = self;
4187        Ok(super::SetSessionConfigOptionResponse {
4188            config_options: into_v2_vec_skip_errors(config_options),
4189            meta: meta.into_v2()?,
4190        })
4191    }
4192}
4193
4194impl IntoV1 for super::McpServer {
4195    type Output = crate::v1::McpServer;
4196
4197    fn into_v1(self) -> Result<Self::Output> {
4198        Ok(match self {
4199            Self::Http(value) => crate::v1::McpServer::Http(value.into_v1()?),
4200            #[cfg(feature = "unstable_mcp_over_acp")]
4201            Self::Acp(value) => crate::v1::McpServer::Acp(value.into_v1()?),
4202            Self::Stdio(value) => crate::v1::McpServer::Stdio(value.into_v1()?),
4203            Self::Other(value) => return Err(unknown_v2_enum_variant("McpServer", &value.type_)),
4204        })
4205    }
4206}
4207
4208impl IntoV2 for crate::v1::McpServer {
4209    type Output = super::McpServer;
4210
4211    fn into_v2(self) -> Result<Self::Output> {
4212        Ok(match self {
4213            Self::Http(value) => super::McpServer::Http(value.into_v2()?),
4214            Self::Sse(_) => return Err(removed_v1_enum_variant("McpServer", "sse")),
4215            #[cfg(feature = "unstable_mcp_over_acp")]
4216            Self::Acp(value) => super::McpServer::Acp(value.into_v2()?),
4217            Self::Stdio(value) => super::McpServer::Stdio(value.into_v2()?),
4218        })
4219    }
4220}
4221
4222impl IntoV1 for super::McpServerHttp {
4223    type Output = crate::v1::McpServerHttp;
4224
4225    fn into_v1(self) -> Result<Self::Output> {
4226        let Self {
4227            name,
4228            url,
4229            headers,
4230            meta,
4231        } = self;
4232        Ok(crate::v1::McpServerHttp {
4233            name: name.into_v1()?,
4234            url: url.into_v1()?,
4235            headers: headers.into_v1()?,
4236            meta: meta.into_v1()?,
4237        })
4238    }
4239}
4240
4241impl IntoV2 for crate::v1::McpServerHttp {
4242    type Output = super::McpServerHttp;
4243
4244    fn into_v2(self) -> Result<Self::Output> {
4245        let Self {
4246            name,
4247            url,
4248            headers,
4249            meta,
4250        } = self;
4251        Ok(super::McpServerHttp {
4252            name: name.into_v2()?,
4253            url: url.into_v2()?,
4254            headers: headers.into_v2()?,
4255            meta: meta.into_v2()?,
4256        })
4257    }
4258}
4259
4260#[cfg(feature = "unstable_mcp_over_acp")]
4261impl IntoV1 for super::McpServerAcpId {
4262    type Output = crate::v1::McpServerAcpId;
4263
4264    fn into_v1(self) -> Result<Self::Output> {
4265        Ok(crate::v1::McpServerAcpId(self.0.into_v1()?))
4266    }
4267}
4268
4269#[cfg(feature = "unstable_mcp_over_acp")]
4270impl IntoV2 for crate::v1::McpServerAcpId {
4271    type Output = super::McpServerAcpId;
4272
4273    fn into_v2(self) -> Result<Self::Output> {
4274        Ok(super::McpServerAcpId(self.0.into_v2()?))
4275    }
4276}
4277
4278#[cfg(feature = "unstable_mcp_over_acp")]
4279impl IntoV1 for super::McpConnectionId {
4280    type Output = crate::v1::McpConnectionId;
4281
4282    fn into_v1(self) -> Result<Self::Output> {
4283        Ok(crate::v1::McpConnectionId(self.0.into_v1()?))
4284    }
4285}
4286
4287#[cfg(feature = "unstable_mcp_over_acp")]
4288impl IntoV2 for crate::v1::McpConnectionId {
4289    type Output = super::McpConnectionId;
4290
4291    fn into_v2(self) -> Result<Self::Output> {
4292        Ok(super::McpConnectionId(self.0.into_v2()?))
4293    }
4294}
4295
4296#[cfg(feature = "unstable_mcp_over_acp")]
4297impl IntoV1 for super::McpServerAcp {
4298    type Output = crate::v1::McpServerAcp;
4299
4300    fn into_v1(self) -> Result<Self::Output> {
4301        let Self {
4302            name,
4303            server_id,
4304            meta,
4305        } = self;
4306        Ok(crate::v1::McpServerAcp {
4307            name: name.into_v1()?,
4308            server_id: server_id.into_v1()?,
4309            meta: meta.into_v1()?,
4310        })
4311    }
4312}
4313
4314#[cfg(feature = "unstable_mcp_over_acp")]
4315impl IntoV2 for crate::v1::McpServerAcp {
4316    type Output = super::McpServerAcp;
4317
4318    fn into_v2(self) -> Result<Self::Output> {
4319        let Self {
4320            name,
4321            server_id,
4322            meta,
4323        } = self;
4324        Ok(super::McpServerAcp {
4325            name: name.into_v2()?,
4326            server_id: server_id.into_v2()?,
4327            meta: meta.into_v2()?,
4328        })
4329    }
4330}
4331
4332impl IntoV1 for super::McpServerStdio {
4333    type Output = crate::v1::McpServerStdio;
4334
4335    fn into_v1(self) -> Result<Self::Output> {
4336        let Self {
4337            name,
4338            command,
4339            args,
4340            env,
4341            meta,
4342        } = self;
4343        Ok(crate::v1::McpServerStdio {
4344            name: name.into_v1()?,
4345            command: command.into_v1()?,
4346            args: args.into_v1()?,
4347            env: env.into_v1()?,
4348            meta: meta.into_v1()?,
4349        })
4350    }
4351}
4352
4353impl IntoV2 for crate::v1::McpServerStdio {
4354    type Output = super::McpServerStdio;
4355
4356    fn into_v2(self) -> Result<Self::Output> {
4357        let Self {
4358            name,
4359            command,
4360            args,
4361            env,
4362            meta,
4363        } = self;
4364        Ok(super::McpServerStdio {
4365            name: name.into_v2()?,
4366            command: command.into_v2()?,
4367            args: args.into_v2()?,
4368            env: env.into_v2()?,
4369            meta: meta.into_v2()?,
4370        })
4371    }
4372}
4373
4374impl IntoV1 for super::EnvVariable {
4375    type Output = crate::v1::EnvVariable;
4376
4377    fn into_v1(self) -> Result<Self::Output> {
4378        let Self { name, value, meta } = self;
4379        Ok(crate::v1::EnvVariable {
4380            name: name.into_v1()?,
4381            value: value.into_v1()?,
4382            meta: meta.into_v1()?,
4383        })
4384    }
4385}
4386
4387impl IntoV2 for crate::v1::EnvVariable {
4388    type Output = super::EnvVariable;
4389
4390    fn into_v2(self) -> Result<Self::Output> {
4391        let Self { name, value, meta } = self;
4392        Ok(super::EnvVariable {
4393            name: name.into_v2()?,
4394            value: value.into_v2()?,
4395            meta: meta.into_v2()?,
4396        })
4397    }
4398}
4399
4400impl IntoV1 for super::HttpHeader {
4401    type Output = crate::v1::HttpHeader;
4402
4403    fn into_v1(self) -> Result<Self::Output> {
4404        let Self { name, value, meta } = self;
4405        Ok(crate::v1::HttpHeader {
4406            name: name.into_v1()?,
4407            value: value.into_v1()?,
4408            meta: meta.into_v1()?,
4409        })
4410    }
4411}
4412
4413impl IntoV2 for crate::v1::HttpHeader {
4414    type Output = super::HttpHeader;
4415
4416    fn into_v2(self) -> Result<Self::Output> {
4417        let Self { name, value, meta } = self;
4418        Ok(super::HttpHeader {
4419            name: name.into_v2()?,
4420            value: value.into_v2()?,
4421            meta: meta.into_v2()?,
4422        })
4423    }
4424}
4425
4426impl IntoV1 for super::PromptRequest {
4427    type Output = crate::v1::PromptRequest;
4428
4429    fn into_v1(self) -> Result<Self::Output> {
4430        let Self {
4431            session_id,
4432            prompt,
4433            meta,
4434        } = self;
4435        Ok(crate::v1::PromptRequest {
4436            session_id: session_id.into_v1()?,
4437            prompt: prompt.into_v1()?,
4438            meta: meta.into_v1()?,
4439        })
4440    }
4441}
4442
4443impl IntoV2 for crate::v1::PromptRequest {
4444    type Output = super::PromptRequest;
4445
4446    fn into_v2(self) -> Result<Self::Output> {
4447        let Self {
4448            session_id,
4449            prompt,
4450            meta,
4451        } = self;
4452        Ok(super::PromptRequest {
4453            session_id: session_id.into_v2()?,
4454            prompt: prompt.into_v2()?,
4455            meta: meta.into_v2()?,
4456        })
4457    }
4458}
4459
4460impl IntoV1 for super::PromptResponse {
4461    type Output = crate::v1::PromptResponse;
4462
4463    fn into_v1(self) -> Result<Self::Output> {
4464        Err(ProtocolConversionError::new(
4465            "v2 PromptResponse cannot be represented in v1 because v2 reports completion with state_update session updates",
4466        ))
4467    }
4468}
4469
4470impl IntoV2 for crate::v1::PromptResponse {
4471    type Output = super::PromptResponse;
4472
4473    fn into_v2(self) -> Result<Self::Output> {
4474        Err(ProtocolConversionError::new(
4475            "v1 PromptResponse cannot be represented in v2 by itself because v2 reports completion with state_update session updates",
4476        ))
4477    }
4478}
4479
4480impl IntoV1 for super::StopReason {
4481    type Output = crate::v1::StopReason;
4482
4483    fn into_v1(self) -> Result<Self::Output> {
4484        Ok(match self {
4485            Self::EndTurn => crate::v1::StopReason::EndTurn,
4486            Self::MaxTokens => crate::v1::StopReason::MaxTokens,
4487            Self::MaxTurnRequests => crate::v1::StopReason::MaxTurnRequests,
4488            Self::Refusal => crate::v1::StopReason::Refusal,
4489            Self::Cancelled => crate::v1::StopReason::Cancelled,
4490            Self::Other(value) => return Err(unknown_v2_enum_variant("StopReason", &value)),
4491        })
4492    }
4493}
4494
4495impl IntoV2 for crate::v1::StopReason {
4496    type Output = super::StopReason;
4497
4498    fn into_v2(self) -> Result<Self::Output> {
4499        Ok(match self {
4500            Self::EndTurn => super::StopReason::EndTurn,
4501            Self::MaxTokens => super::StopReason::MaxTokens,
4502            Self::MaxTurnRequests => super::StopReason::MaxTurnRequests,
4503            Self::Refusal => super::StopReason::Refusal,
4504            Self::Cancelled => super::StopReason::Cancelled,
4505        })
4506    }
4507}
4508
4509#[cfg(feature = "unstable_end_turn_token_usage")]
4510impl IntoV1 for super::Usage {
4511    type Output = crate::v1::Usage;
4512
4513    fn into_v1(self) -> Result<Self::Output> {
4514        let Self {
4515            total_tokens,
4516            input_tokens,
4517            output_tokens,
4518            thought_tokens,
4519            cached_read_tokens,
4520            cached_write_tokens,
4521            meta,
4522        } = self;
4523        Ok(crate::v1::Usage {
4524            total_tokens: total_tokens.into_v1()?,
4525            input_tokens: input_tokens.into_v1()?,
4526            output_tokens: output_tokens.into_v1()?,
4527            thought_tokens: thought_tokens.into_v1()?,
4528            cached_read_tokens: cached_read_tokens.into_v1()?,
4529            cached_write_tokens: cached_write_tokens.into_v1()?,
4530            meta: meta.into_v1()?,
4531        })
4532    }
4533}
4534
4535#[cfg(feature = "unstable_end_turn_token_usage")]
4536impl IntoV2 for crate::v1::Usage {
4537    type Output = super::Usage;
4538
4539    fn into_v2(self) -> Result<Self::Output> {
4540        let Self {
4541            total_tokens,
4542            input_tokens,
4543            output_tokens,
4544            thought_tokens,
4545            cached_read_tokens,
4546            cached_write_tokens,
4547            meta,
4548        } = self;
4549        Ok(super::Usage {
4550            total_tokens: total_tokens.into_v2()?,
4551            input_tokens: input_tokens.into_v2()?,
4552            output_tokens: output_tokens.into_v2()?,
4553            thought_tokens: thought_tokens.into_v2()?,
4554            cached_read_tokens: cached_read_tokens.into_v2()?,
4555            cached_write_tokens: cached_write_tokens.into_v2()?,
4556            meta: meta.into_v2()?,
4557        })
4558    }
4559}
4560
4561#[cfg(feature = "unstable_llm_providers")]
4562impl IntoV1 for super::LlmProtocol {
4563    type Output = crate::v1::LlmProtocol;
4564
4565    fn into_v1(self) -> Result<Self::Output> {
4566        Ok(match self {
4567            Self::Anthropic => crate::v1::LlmProtocol::Anthropic,
4568            Self::OpenAi => crate::v1::LlmProtocol::OpenAi,
4569            Self::Azure => crate::v1::LlmProtocol::Azure,
4570            Self::Vertex => crate::v1::LlmProtocol::Vertex,
4571            Self::Bedrock => crate::v1::LlmProtocol::Bedrock,
4572            Self::Other(value) => crate::v1::LlmProtocol::Other(value.into_v1()?),
4573        })
4574    }
4575}
4576
4577#[cfg(feature = "unstable_llm_providers")]
4578impl IntoV2 for crate::v1::LlmProtocol {
4579    type Output = super::LlmProtocol;
4580
4581    fn into_v2(self) -> Result<Self::Output> {
4582        Ok(match self {
4583            Self::Anthropic => super::LlmProtocol::Anthropic,
4584            Self::OpenAi => super::LlmProtocol::OpenAi,
4585            Self::Azure => super::LlmProtocol::Azure,
4586            Self::Vertex => super::LlmProtocol::Vertex,
4587            Self::Bedrock => super::LlmProtocol::Bedrock,
4588            Self::Other(value) => super::LlmProtocol::Other(value.into_v2()?),
4589        })
4590    }
4591}
4592
4593#[cfg(feature = "unstable_llm_providers")]
4594impl IntoV1 for super::ProviderCurrentConfig {
4595    type Output = crate::v1::ProviderCurrentConfig;
4596
4597    fn into_v1(self) -> Result<Self::Output> {
4598        let Self {
4599            api_type,
4600            base_url,
4601            meta,
4602        } = self;
4603        Ok(crate::v1::ProviderCurrentConfig {
4604            api_type: api_type.into_v1()?,
4605            base_url: base_url.into_v1()?,
4606            meta: meta.into_v1()?,
4607        })
4608    }
4609}
4610
4611#[cfg(feature = "unstable_llm_providers")]
4612impl IntoV2 for crate::v1::ProviderCurrentConfig {
4613    type Output = super::ProviderCurrentConfig;
4614
4615    fn into_v2(self) -> Result<Self::Output> {
4616        let Self {
4617            api_type,
4618            base_url,
4619            meta,
4620        } = self;
4621        Ok(super::ProviderCurrentConfig {
4622            api_type: api_type.into_v2()?,
4623            base_url: base_url.into_v2()?,
4624            meta: meta.into_v2()?,
4625        })
4626    }
4627}
4628
4629#[cfg(feature = "unstable_llm_providers")]
4630impl IntoV1 for super::ProviderId {
4631    type Output = crate::v1::ProviderId;
4632
4633    fn into_v1(self) -> Result<Self::Output> {
4634        Ok(crate::v1::ProviderId(self.0.into_v1()?))
4635    }
4636}
4637
4638#[cfg(feature = "unstable_llm_providers")]
4639impl IntoV2 for crate::v1::ProviderId {
4640    type Output = super::ProviderId;
4641
4642    fn into_v2(self) -> Result<Self::Output> {
4643        Ok(super::ProviderId(self.0.into_v2()?))
4644    }
4645}
4646
4647#[cfg(feature = "unstable_llm_providers")]
4648impl IntoV1 for super::ProviderInfo {
4649    type Output = crate::v1::ProviderInfo;
4650
4651    fn into_v1(self) -> Result<Self::Output> {
4652        let Self {
4653            provider_id,
4654            supported,
4655            required,
4656            current,
4657            meta,
4658        } = self;
4659        Ok(crate::v1::ProviderInfo {
4660            provider_id: provider_id.into_v1()?,
4661            supported: into_v1_vec_skip_errors(supported),
4662            required: required.into_v1()?,
4663            current: current.into_v1()?,
4664            meta: meta.into_v1()?,
4665        })
4666    }
4667}
4668
4669#[cfg(feature = "unstable_llm_providers")]
4670impl IntoV2 for crate::v1::ProviderInfo {
4671    type Output = super::ProviderInfo;
4672
4673    fn into_v2(self) -> Result<Self::Output> {
4674        let Self {
4675            provider_id,
4676            supported,
4677            required,
4678            current,
4679            meta,
4680        } = self;
4681        Ok(super::ProviderInfo {
4682            provider_id: provider_id.into_v2()?,
4683            supported: into_v2_vec_skip_errors(supported),
4684            required: required.into_v2()?,
4685            current: current.into_v2()?,
4686            meta: meta.into_v2()?,
4687        })
4688    }
4689}
4690
4691#[cfg(feature = "unstable_llm_providers")]
4692impl IntoV1 for super::ListProvidersRequest {
4693    type Output = crate::v1::ListProvidersRequest;
4694
4695    fn into_v1(self) -> Result<Self::Output> {
4696        let Self { meta } = self;
4697        Ok(crate::v1::ListProvidersRequest {
4698            meta: meta.into_v1()?,
4699        })
4700    }
4701}
4702
4703#[cfg(feature = "unstable_llm_providers")]
4704impl IntoV2 for crate::v1::ListProvidersRequest {
4705    type Output = super::ListProvidersRequest;
4706
4707    fn into_v2(self) -> Result<Self::Output> {
4708        let Self { meta } = self;
4709        Ok(super::ListProvidersRequest {
4710            meta: meta.into_v2()?,
4711        })
4712    }
4713}
4714
4715#[cfg(feature = "unstable_llm_providers")]
4716impl IntoV1 for super::ListProvidersResponse {
4717    type Output = crate::v1::ListProvidersResponse;
4718
4719    fn into_v1(self) -> Result<Self::Output> {
4720        let Self { providers, meta } = self;
4721        Ok(crate::v1::ListProvidersResponse {
4722            providers: into_v1_vec_skip_errors(providers),
4723            meta: meta.into_v1()?,
4724        })
4725    }
4726}
4727
4728#[cfg(feature = "unstable_llm_providers")]
4729impl IntoV2 for crate::v1::ListProvidersResponse {
4730    type Output = super::ListProvidersResponse;
4731
4732    fn into_v2(self) -> Result<Self::Output> {
4733        let Self { providers, meta } = self;
4734        Ok(super::ListProvidersResponse {
4735            providers: into_v2_vec_skip_errors(providers),
4736            meta: meta.into_v2()?,
4737        })
4738    }
4739}
4740
4741#[cfg(feature = "unstable_llm_providers")]
4742impl IntoV1 for super::SetProviderRequest {
4743    type Output = crate::v1::SetProviderRequest;
4744
4745    fn into_v1(self) -> Result<Self::Output> {
4746        let Self {
4747            provider_id,
4748            api_type,
4749            base_url,
4750            headers,
4751            meta,
4752        } = self;
4753        Ok(crate::v1::SetProviderRequest {
4754            provider_id: provider_id.into_v1()?,
4755            api_type: api_type.into_v1()?,
4756            base_url: base_url.into_v1()?,
4757            headers: headers.into_v1()?,
4758            meta: meta.into_v1()?,
4759        })
4760    }
4761}
4762
4763#[cfg(feature = "unstable_llm_providers")]
4764impl IntoV2 for crate::v1::SetProviderRequest {
4765    type Output = super::SetProviderRequest;
4766
4767    fn into_v2(self) -> Result<Self::Output> {
4768        let Self {
4769            provider_id,
4770            api_type,
4771            base_url,
4772            headers,
4773            meta,
4774        } = self;
4775        Ok(super::SetProviderRequest {
4776            provider_id: provider_id.into_v2()?,
4777            api_type: api_type.into_v2()?,
4778            base_url: base_url.into_v2()?,
4779            headers: headers.into_v2()?,
4780            meta: meta.into_v2()?,
4781        })
4782    }
4783}
4784
4785#[cfg(feature = "unstable_llm_providers")]
4786impl IntoV1 for super::SetProviderResponse {
4787    type Output = crate::v1::SetProviderResponse;
4788
4789    fn into_v1(self) -> Result<Self::Output> {
4790        let Self { meta } = self;
4791        Ok(crate::v1::SetProviderResponse {
4792            meta: meta.into_v1()?,
4793        })
4794    }
4795}
4796
4797#[cfg(feature = "unstable_llm_providers")]
4798impl IntoV2 for crate::v1::SetProviderResponse {
4799    type Output = super::SetProviderResponse;
4800
4801    fn into_v2(self) -> Result<Self::Output> {
4802        let Self { meta } = self;
4803        Ok(super::SetProviderResponse {
4804            meta: meta.into_v2()?,
4805        })
4806    }
4807}
4808
4809#[cfg(feature = "unstable_llm_providers")]
4810impl IntoV1 for super::DisableProviderRequest {
4811    type Output = crate::v1::DisableProviderRequest;
4812
4813    fn into_v1(self) -> Result<Self::Output> {
4814        let Self { provider_id, meta } = self;
4815        Ok(crate::v1::DisableProviderRequest {
4816            provider_id: provider_id.into_v1()?,
4817            meta: meta.into_v1()?,
4818        })
4819    }
4820}
4821
4822#[cfg(feature = "unstable_llm_providers")]
4823impl IntoV2 for crate::v1::DisableProviderRequest {
4824    type Output = super::DisableProviderRequest;
4825
4826    fn into_v2(self) -> Result<Self::Output> {
4827        let Self { provider_id, meta } = self;
4828        Ok(super::DisableProviderRequest {
4829            provider_id: provider_id.into_v2()?,
4830            meta: meta.into_v2()?,
4831        })
4832    }
4833}
4834
4835#[cfg(feature = "unstable_llm_providers")]
4836impl IntoV1 for super::DisableProviderResponse {
4837    type Output = crate::v1::DisableProviderResponse;
4838
4839    fn into_v1(self) -> Result<Self::Output> {
4840        let Self { meta } = self;
4841        Ok(crate::v1::DisableProviderResponse {
4842            meta: meta.into_v1()?,
4843        })
4844    }
4845}
4846
4847#[cfg(feature = "unstable_llm_providers")]
4848impl IntoV2 for crate::v1::DisableProviderResponse {
4849    type Output = super::DisableProviderResponse;
4850
4851    fn into_v2(self) -> Result<Self::Output> {
4852        let Self { meta } = self;
4853        Ok(super::DisableProviderResponse {
4854            meta: meta.into_v2()?,
4855        })
4856    }
4857}
4858
4859impl IntoV1 for super::AgentCapabilities {
4860    type Output = crate::v1::AgentCapabilities;
4861
4862    fn into_v1(self) -> Result<Self::Output> {
4863        let Self {
4864            session,
4865            auth,
4866            #[cfg(feature = "unstable_llm_providers")]
4867            providers,
4868            #[cfg(feature = "unstable_nes")]
4869            nes,
4870            #[cfg(feature = "unstable_nes")]
4871            position_encoding,
4872            meta,
4873        } = self;
4874        let Some(session) = session else {
4875            return Err(ProtocolConversionError::new(
4876                "v2 AgentCapabilities without `session` cannot be represented in v1",
4877            ));
4878        };
4879        let V1SessionCapabilityParts {
4880            session_capabilities,
4881            prompt_capabilities,
4882            load_session,
4883            mcp_capabilities,
4884        } = session.into_v1()?;
4885
4886        Ok(crate::v1::AgentCapabilities {
4887            load_session: load_session.into_v1()?,
4888            prompt_capabilities,
4889            mcp_capabilities,
4890            session_capabilities,
4891            auth: auth.map(IntoV1::into_v1).transpose()?.unwrap_or_default(),
4892            #[cfg(feature = "unstable_llm_providers")]
4893            providers: into_v1_default_on_error(providers),
4894            #[cfg(feature = "unstable_nes")]
4895            nes: into_v1_default_on_error(nes),
4896            #[cfg(feature = "unstable_nes")]
4897            position_encoding: into_v1_default_on_error(position_encoding),
4898            meta: meta.into_v1()?,
4899        })
4900    }
4901}
4902
4903impl IntoV2 for crate::v1::AgentCapabilities {
4904    type Output = super::AgentCapabilities;
4905
4906    fn into_v2(self) -> Result<Self::Output> {
4907        let Self {
4908            load_session,
4909            prompt_capabilities,
4910            mcp_capabilities,
4911            session_capabilities,
4912            auth,
4913            #[cfg(feature = "unstable_llm_providers")]
4914            providers,
4915            #[cfg(feature = "unstable_nes")]
4916            nes,
4917            #[cfg(feature = "unstable_nes")]
4918            position_encoding,
4919            meta,
4920        } = self;
4921        let session = super::SessionCapabilities::from_v1(
4922            session_capabilities,
4923            prompt_capabilities,
4924            load_session,
4925            mcp_capabilities,
4926        )?;
4927
4928        Ok(super::AgentCapabilities {
4929            session: Some(session),
4930            auth: Some(auth.into_v2()?),
4931            #[cfg(feature = "unstable_llm_providers")]
4932            providers: into_v2_default_on_error(providers),
4933            #[cfg(feature = "unstable_nes")]
4934            nes: into_v2_default_on_error(nes),
4935            #[cfg(feature = "unstable_nes")]
4936            position_encoding: into_v2_default_on_error(position_encoding),
4937            meta: meta.into_v2()?,
4938        })
4939    }
4940}
4941
4942#[cfg(feature = "unstable_llm_providers")]
4943impl IntoV1 for super::ProvidersCapabilities {
4944    type Output = crate::v1::ProvidersCapabilities;
4945
4946    fn into_v1(self) -> Result<Self::Output> {
4947        let Self { meta } = self;
4948        Ok(crate::v1::ProvidersCapabilities {
4949            meta: meta.into_v1()?,
4950        })
4951    }
4952}
4953
4954#[cfg(feature = "unstable_llm_providers")]
4955impl IntoV2 for crate::v1::ProvidersCapabilities {
4956    type Output = super::ProvidersCapabilities;
4957
4958    fn into_v2(self) -> Result<Self::Output> {
4959        let Self { meta } = self;
4960        Ok(super::ProvidersCapabilities {
4961            meta: meta.into_v2()?,
4962        })
4963    }
4964}
4965
4966/// The v1 capability fields represented by v2 `SessionCapabilities`.
4967#[derive(Debug, Clone, PartialEq, Eq)]
4968#[non_exhaustive]
4969pub struct V1SessionCapabilityParts {
4970    /// Session-specific v1 capabilities.
4971    pub session_capabilities: crate::v1::SessionCapabilities,
4972    /// Prompt capabilities for v1 `session/prompt` requests.
4973    pub prompt_capabilities: crate::v1::PromptCapabilities,
4974    /// Whether v1 `session/load` is supported.
4975    pub load_session: bool,
4976    /// MCP capabilities for v1 session lifecycle requests.
4977    pub mcp_capabilities: crate::v1::McpCapabilities,
4978}
4979
4980impl super::SessionCapabilities {
4981    /// Converts these v2 draft session capabilities into the v1 capability
4982    /// fields they represent.
4983    ///
4984    /// # Errors
4985    ///
4986    /// Returns [`ProtocolConversionError`] when any contained capability field
4987    /// cannot be represented in v1.
4988    pub fn into_v1(self) -> Result<V1SessionCapabilityParts> {
4989        let Self {
4990            prompt,
4991            mcp,
4992            delete,
4993            additional_directories,
4994            #[cfg(feature = "unstable_session_fork")]
4995            fork,
4996            meta,
4997        } = self;
4998
4999        Ok(V1SessionCapabilityParts {
5000            session_capabilities: crate::v1::SessionCapabilities {
5001                list: Some(crate::v1::SessionListCapabilities::new()),
5002                delete: into_v1_default_on_error(delete),
5003                additional_directories: into_v1_default_on_error(additional_directories),
5004                #[cfg(feature = "unstable_session_fork")]
5005                fork: into_v1_default_on_error(fork),
5006                resume: Some(crate::v1::SessionResumeCapabilities::new()),
5007                close: Some(crate::v1::SessionCloseCapabilities::new()),
5008                meta: meta.into_v1()?,
5009            },
5010            prompt_capabilities: prompt.unwrap_or_default().into_v1()?,
5011            load_session: true,
5012            mcp_capabilities: mcp.unwrap_or_default().into_v1()?,
5013        })
5014    }
5015
5016    /// Builds v2 draft session capabilities from the v1 agent capability fields
5017    /// that now live under `session` in v2.
5018    ///
5019    /// # Errors
5020    ///
5021    /// Returns [`ProtocolConversionError`] when any of the supplied v1
5022    /// capability fields cannot be represented in v2.
5023    pub fn from_v1(
5024        session_capabilities: crate::v1::SessionCapabilities,
5025        prompt_capabilities: crate::v1::PromptCapabilities,
5026        _load_session: bool,
5027        mcp_capabilities: crate::v1::McpCapabilities,
5028    ) -> Result<Self> {
5029        let crate::v1::SessionCapabilities {
5030            list: _,
5031            delete,
5032            additional_directories,
5033            #[cfg(feature = "unstable_session_fork")]
5034            fork,
5035            resume: _,
5036            close: _,
5037            meta,
5038        } = session_capabilities;
5039
5040        Ok(super::SessionCapabilities {
5041            prompt: Some(prompt_capabilities.into_v2()?),
5042            mcp: Some(mcp_capabilities.into_v2()?),
5043            delete: into_v2_default_on_error(delete),
5044            additional_directories: into_v2_default_on_error(additional_directories),
5045            #[cfg(feature = "unstable_session_fork")]
5046            fork: into_v2_default_on_error(fork),
5047            meta: meta.into_v2()?,
5048        })
5049    }
5050}
5051
5052impl IntoV1 for super::SessionDeleteCapabilities {
5053    type Output = crate::v1::SessionDeleteCapabilities;
5054
5055    fn into_v1(self) -> Result<Self::Output> {
5056        let Self { meta } = self;
5057        Ok(crate::v1::SessionDeleteCapabilities {
5058            meta: meta.into_v1()?,
5059        })
5060    }
5061}
5062
5063impl IntoV2 for crate::v1::SessionDeleteCapabilities {
5064    type Output = super::SessionDeleteCapabilities;
5065
5066    fn into_v2(self) -> Result<Self::Output> {
5067        let Self { meta } = self;
5068        Ok(super::SessionDeleteCapabilities {
5069            meta: meta.into_v2()?,
5070        })
5071    }
5072}
5073impl IntoV1 for super::SessionAdditionalDirectoriesCapabilities {
5074    type Output = crate::v1::SessionAdditionalDirectoriesCapabilities;
5075
5076    fn into_v1(self) -> Result<Self::Output> {
5077        let Self { meta } = self;
5078        Ok(crate::v1::SessionAdditionalDirectoriesCapabilities {
5079            meta: meta.into_v1()?,
5080        })
5081    }
5082}
5083
5084impl IntoV2 for crate::v1::SessionAdditionalDirectoriesCapabilities {
5085    type Output = super::SessionAdditionalDirectoriesCapabilities;
5086
5087    fn into_v2(self) -> Result<Self::Output> {
5088        let Self { meta } = self;
5089        Ok(super::SessionAdditionalDirectoriesCapabilities {
5090            meta: meta.into_v2()?,
5091        })
5092    }
5093}
5094
5095#[cfg(feature = "unstable_session_fork")]
5096impl IntoV1 for super::SessionForkCapabilities {
5097    type Output = crate::v1::SessionForkCapabilities;
5098
5099    fn into_v1(self) -> Result<Self::Output> {
5100        let Self { meta } = self;
5101        Ok(crate::v1::SessionForkCapabilities {
5102            meta: meta.into_v1()?,
5103        })
5104    }
5105}
5106
5107#[cfg(feature = "unstable_session_fork")]
5108impl IntoV2 for crate::v1::SessionForkCapabilities {
5109    type Output = super::SessionForkCapabilities;
5110
5111    fn into_v2(self) -> Result<Self::Output> {
5112        let Self { meta } = self;
5113        Ok(super::SessionForkCapabilities {
5114            meta: meta.into_v2()?,
5115        })
5116    }
5117}
5118
5119impl IntoV1 for super::PromptCapabilities {
5120    type Output = crate::v1::PromptCapabilities;
5121
5122    fn into_v1(self) -> Result<Self::Output> {
5123        let Self {
5124            image,
5125            audio,
5126            embedded_context,
5127            meta,
5128        } = self;
5129        Ok(crate::v1::PromptCapabilities {
5130            image: image.is_some(),
5131            audio: audio.is_some(),
5132            embedded_context: embedded_context.is_some(),
5133            meta: meta.into_v1()?,
5134        })
5135    }
5136}
5137
5138impl IntoV2 for crate::v1::PromptCapabilities {
5139    type Output = super::PromptCapabilities;
5140
5141    fn into_v2(self) -> Result<Self::Output> {
5142        let Self {
5143            image,
5144            audio,
5145            embedded_context,
5146            meta,
5147        } = self;
5148        Ok(super::PromptCapabilities {
5149            image: image.then(super::PromptImageCapabilities::new),
5150            audio: audio.then(super::PromptAudioCapabilities::new),
5151            embedded_context: embedded_context.then(super::PromptEmbeddedContextCapabilities::new),
5152            meta: meta.into_v2()?,
5153        })
5154    }
5155}
5156
5157impl IntoV1 for super::McpCapabilities {
5158    type Output = crate::v1::McpCapabilities;
5159
5160    fn into_v1(self) -> Result<Self::Output> {
5161        let Self {
5162            stdio: _,
5163            http,
5164            #[cfg(feature = "unstable_mcp_over_acp")]
5165            acp,
5166            meta,
5167        } = self;
5168        Ok(crate::v1::McpCapabilities {
5169            http: http.is_some(),
5170            sse: false,
5171            #[cfg(feature = "unstable_mcp_over_acp")]
5172            acp: acp.is_some(),
5173            meta: meta.into_v1()?,
5174        })
5175    }
5176}
5177
5178impl IntoV2 for crate::v1::McpCapabilities {
5179    type Output = super::McpCapabilities;
5180
5181    fn into_v2(self) -> Result<Self::Output> {
5182        let Self {
5183            http,
5184            sse: _,
5185            #[cfg(feature = "unstable_mcp_over_acp")]
5186            acp,
5187            meta,
5188        } = self;
5189        Ok(super::McpCapabilities {
5190            stdio: Some(super::McpStdioCapabilities::new()),
5191            http: http.then(super::McpHttpCapabilities::new),
5192            #[cfg(feature = "unstable_mcp_over_acp")]
5193            acp: acp.then(super::McpAcpCapabilities::new),
5194            meta: meta.into_v2()?,
5195        })
5196    }
5197}
5198
5199impl IntoV1 for super::ClientRequest {
5200    type Output = crate::v1::ClientRequest;
5201
5202    fn into_v1(self) -> Result<Self::Output> {
5203        Ok(match self {
5204            Self::InitializeRequest(value) => {
5205                crate::v1::ClientRequest::InitializeRequest(value.into_v1()?)
5206            }
5207            Self::LoginAuthRequest(value) => {
5208                crate::v1::ClientRequest::AuthenticateRequest(value.into_v1()?)
5209            }
5210            #[cfg(feature = "unstable_llm_providers")]
5211            Self::ListProvidersRequest(value) => {
5212                crate::v1::ClientRequest::ListProvidersRequest(value.into_v1()?)
5213            }
5214            #[cfg(feature = "unstable_llm_providers")]
5215            Self::SetProviderRequest(value) => {
5216                crate::v1::ClientRequest::SetProviderRequest(value.into_v1()?)
5217            }
5218            #[cfg(feature = "unstable_llm_providers")]
5219            Self::DisableProviderRequest(value) => {
5220                crate::v1::ClientRequest::DisableProviderRequest(value.into_v1()?)
5221            }
5222            Self::LogoutAuthRequest(value) => {
5223                crate::v1::ClientRequest::LogoutRequest(value.into_v1()?)
5224            }
5225            Self::NewSessionRequest(value) => {
5226                crate::v1::ClientRequest::NewSessionRequest(value.into_v1()?)
5227            }
5228            Self::ListSessionsRequest(value) => {
5229                crate::v1::ClientRequest::ListSessionsRequest(value.into_v1()?)
5230            }
5231            Self::DeleteSessionRequest(value) => {
5232                crate::v1::ClientRequest::DeleteSessionRequest(value.into_v1()?)
5233            }
5234            #[cfg(feature = "unstable_session_fork")]
5235            Self::ForkSessionRequest(value) => {
5236                crate::v1::ClientRequest::ForkSessionRequest(value.into_v1()?)
5237            }
5238            Self::ResumeSessionRequest(value) => {
5239                v2_resume_session_request_into_v1_client_request(*value)?
5240            }
5241            Self::CloseSessionRequest(value) => {
5242                crate::v1::ClientRequest::CloseSessionRequest(value.into_v1()?)
5243            }
5244            Self::SetSessionConfigOptionRequest(value) => {
5245                crate::v1::ClientRequest::SetSessionConfigOptionRequest(value.into_v1()?)
5246            }
5247            Self::PromptRequest(value) => crate::v1::ClientRequest::PromptRequest(value.into_v1()?),
5248            #[cfg(feature = "unstable_nes")]
5249            Self::StartNesRequest(value) => {
5250                crate::v1::ClientRequest::StartNesRequest(value.into_v1()?)
5251            }
5252            #[cfg(feature = "unstable_nes")]
5253            Self::SuggestNesRequest(value) => {
5254                crate::v1::ClientRequest::SuggestNesRequest(value.into_v1()?)
5255            }
5256            #[cfg(feature = "unstable_nes")]
5257            Self::CloseNesRequest(value) => {
5258                crate::v1::ClientRequest::CloseNesRequest(value.into_v1()?)
5259            }
5260            #[cfg(feature = "unstable_mcp_over_acp")]
5261            Self::MessageMcpRequest(value) => {
5262                crate::v1::ClientRequest::MessageMcpRequest(value.into_v1()?)
5263            }
5264            Self::ExtMethodRequest(value) => {
5265                crate::v1::ClientRequest::ExtMethodRequest(value.into_v1()?)
5266            }
5267        })
5268    }
5269}
5270
5271impl IntoV2 for crate::v1::ClientRequest {
5272    type Output = super::ClientRequest;
5273
5274    fn into_v2(self) -> Result<Self::Output> {
5275        Ok(match self {
5276            Self::InitializeRequest(value) => {
5277                super::ClientRequest::InitializeRequest(Box::new(value.into_v2()?))
5278            }
5279            Self::AuthenticateRequest(value) => {
5280                super::ClientRequest::LoginAuthRequest(Box::new(value.into_v2()?))
5281            }
5282            #[cfg(feature = "unstable_llm_providers")]
5283            Self::ListProvidersRequest(value) => {
5284                super::ClientRequest::ListProvidersRequest(Box::new(value.into_v2()?))
5285            }
5286            #[cfg(feature = "unstable_llm_providers")]
5287            Self::SetProviderRequest(value) => {
5288                super::ClientRequest::SetProviderRequest(Box::new(value.into_v2()?))
5289            }
5290            #[cfg(feature = "unstable_llm_providers")]
5291            Self::DisableProviderRequest(value) => {
5292                super::ClientRequest::DisableProviderRequest(Box::new(value.into_v2()?))
5293            }
5294            Self::LogoutRequest(value) => {
5295                super::ClientRequest::LogoutAuthRequest(Box::new(value.into_v2()?))
5296            }
5297            Self::NewSessionRequest(value) => {
5298                super::ClientRequest::NewSessionRequest(Box::new(value.into_v2()?))
5299            }
5300            Self::LoadSessionRequest(value) => {
5301                super::ClientRequest::ResumeSessionRequest(Box::new(value.into_v2()?))
5302            }
5303            Self::ListSessionsRequest(value) => {
5304                super::ClientRequest::ListSessionsRequest(Box::new(value.into_v2()?))
5305            }
5306            Self::DeleteSessionRequest(value) => {
5307                super::ClientRequest::DeleteSessionRequest(Box::new(value.into_v2()?))
5308            }
5309            #[cfg(feature = "unstable_session_fork")]
5310            Self::ForkSessionRequest(value) => {
5311                super::ClientRequest::ForkSessionRequest(Box::new(value.into_v2()?))
5312            }
5313            Self::ResumeSessionRequest(value) => {
5314                super::ClientRequest::ResumeSessionRequest(Box::new(value.into_v2()?))
5315            }
5316            Self::CloseSessionRequest(value) => {
5317                super::ClientRequest::CloseSessionRequest(Box::new(value.into_v2()?))
5318            }
5319            Self::SetSessionModeRequest(_) => {
5320                return Err(removed_v1_enum_variant("ClientRequest", "session/set_mode"));
5321            }
5322            Self::SetSessionConfigOptionRequest(value) => {
5323                super::ClientRequest::SetSessionConfigOptionRequest(Box::new(value.into_v2()?))
5324            }
5325            Self::PromptRequest(value) => {
5326                super::ClientRequest::PromptRequest(Box::new(value.into_v2()?))
5327            }
5328            #[cfg(feature = "unstable_nes")]
5329            Self::StartNesRequest(value) => {
5330                super::ClientRequest::StartNesRequest(Box::new(value.into_v2()?))
5331            }
5332            #[cfg(feature = "unstable_nes")]
5333            Self::SuggestNesRequest(value) => {
5334                super::ClientRequest::SuggestNesRequest(Box::new(value.into_v2()?))
5335            }
5336            #[cfg(feature = "unstable_nes")]
5337            Self::CloseNesRequest(value) => {
5338                super::ClientRequest::CloseNesRequest(Box::new(value.into_v2()?))
5339            }
5340            #[cfg(feature = "unstable_mcp_over_acp")]
5341            Self::MessageMcpRequest(value) => {
5342                super::ClientRequest::MessageMcpRequest(Box::new(value.into_v2()?))
5343            }
5344            Self::ExtMethodRequest(value) => {
5345                super::ClientRequest::ExtMethodRequest(Box::new(value.into_v2()?))
5346            }
5347        })
5348    }
5349}
5350
5351impl IntoV1 for super::AgentResponse {
5352    type Output = crate::v1::AgentResponse;
5353
5354    fn into_v1(self) -> Result<Self::Output> {
5355        Ok(match self {
5356            Self::InitializeResponse(value) => {
5357                crate::v1::AgentResponse::InitializeResponse(value.into_v1()?)
5358            }
5359            Self::LoginAuthResponse(value) => {
5360                crate::v1::AgentResponse::AuthenticateResponse(value.into_v1()?)
5361            }
5362            #[cfg(feature = "unstable_llm_providers")]
5363            Self::ListProvidersResponse(value) => {
5364                crate::v1::AgentResponse::ListProvidersResponse(value.into_v1()?)
5365            }
5366            #[cfg(feature = "unstable_llm_providers")]
5367            Self::SetProviderResponse(value) => {
5368                crate::v1::AgentResponse::SetProviderResponse(value.into_v1()?)
5369            }
5370            #[cfg(feature = "unstable_llm_providers")]
5371            Self::DisableProviderResponse(value) => {
5372                crate::v1::AgentResponse::DisableProviderResponse(value.into_v1()?)
5373            }
5374            Self::LogoutAuthResponse(value) => {
5375                crate::v1::AgentResponse::LogoutResponse(value.into_v1()?)
5376            }
5377            Self::NewSessionResponse(value) => {
5378                crate::v1::AgentResponse::NewSessionResponse(value.into_v1()?)
5379            }
5380            Self::ListSessionsResponse(value) => {
5381                crate::v1::AgentResponse::ListSessionsResponse(value.into_v1()?)
5382            }
5383            Self::DeleteSessionResponse(value) => {
5384                crate::v1::AgentResponse::DeleteSessionResponse(value.into_v1()?)
5385            }
5386            #[cfg(feature = "unstable_session_fork")]
5387            Self::ForkSessionResponse(value) => {
5388                crate::v1::AgentResponse::ForkSessionResponse(value.into_v1()?)
5389            }
5390            Self::ResumeSessionResponse(value) => {
5391                crate::v1::AgentResponse::ResumeSessionResponse(value.into_v1()?)
5392            }
5393            Self::CloseSessionResponse(value) => {
5394                crate::v1::AgentResponse::CloseSessionResponse(value.into_v1()?)
5395            }
5396            Self::SetSessionConfigOptionResponse(value) => {
5397                crate::v1::AgentResponse::SetSessionConfigOptionResponse(value.into_v1()?)
5398            }
5399            Self::PromptResponse(value) => {
5400                crate::v1::AgentResponse::PromptResponse(value.into_v1()?)
5401            }
5402            #[cfg(feature = "unstable_nes")]
5403            Self::StartNesResponse(value) => {
5404                crate::v1::AgentResponse::StartNesResponse(value.into_v1()?)
5405            }
5406            #[cfg(feature = "unstable_nes")]
5407            Self::SuggestNesResponse(value) => {
5408                crate::v1::AgentResponse::SuggestNesResponse(value.into_v1()?)
5409            }
5410            #[cfg(feature = "unstable_nes")]
5411            Self::CloseNesResponse(value) => {
5412                crate::v1::AgentResponse::CloseNesResponse(value.into_v1()?)
5413            }
5414            Self::ExtMethodResponse(value) => {
5415                crate::v1::AgentResponse::ExtMethodResponse(value.into_v1()?)
5416            }
5417            #[cfg(feature = "unstable_mcp_over_acp")]
5418            Self::MessageMcpResponse(value) => {
5419                crate::v1::AgentResponse::MessageMcpResponse(value.into_v1()?)
5420            }
5421        })
5422    }
5423}
5424
5425impl IntoV2 for crate::v1::AgentResponse {
5426    type Output = super::AgentResponse;
5427
5428    fn into_v2(self) -> Result<Self::Output> {
5429        Ok(match self {
5430            Self::InitializeResponse(value) => {
5431                super::AgentResponse::InitializeResponse(Box::new(value.into_v2()?))
5432            }
5433            Self::AuthenticateResponse(value) => {
5434                super::AgentResponse::LoginAuthResponse(Box::new(value.into_v2()?))
5435            }
5436            #[cfg(feature = "unstable_llm_providers")]
5437            Self::ListProvidersResponse(value) => {
5438                super::AgentResponse::ListProvidersResponse(Box::new(value.into_v2()?))
5439            }
5440            #[cfg(feature = "unstable_llm_providers")]
5441            Self::SetProviderResponse(value) => {
5442                super::AgentResponse::SetProviderResponse(Box::new(value.into_v2()?))
5443            }
5444            #[cfg(feature = "unstable_llm_providers")]
5445            Self::DisableProviderResponse(value) => {
5446                super::AgentResponse::DisableProviderResponse(Box::new(value.into_v2()?))
5447            }
5448            Self::LogoutResponse(value) => {
5449                super::AgentResponse::LogoutAuthResponse(Box::new(value.into_v2()?))
5450            }
5451            Self::NewSessionResponse(value) => {
5452                super::AgentResponse::NewSessionResponse(Box::new(value.into_v2()?))
5453            }
5454            Self::LoadSessionResponse(value) => {
5455                super::AgentResponse::ResumeSessionResponse(Box::new(value.into_v2()?))
5456            }
5457            Self::ListSessionsResponse(value) => {
5458                super::AgentResponse::ListSessionsResponse(Box::new(value.into_v2()?))
5459            }
5460            Self::DeleteSessionResponse(value) => {
5461                super::AgentResponse::DeleteSessionResponse(Box::new(value.into_v2()?))
5462            }
5463            #[cfg(feature = "unstable_session_fork")]
5464            Self::ForkSessionResponse(value) => {
5465                super::AgentResponse::ForkSessionResponse(Box::new(value.into_v2()?))
5466            }
5467            Self::ResumeSessionResponse(value) => {
5468                super::AgentResponse::ResumeSessionResponse(Box::new(value.into_v2()?))
5469            }
5470            Self::CloseSessionResponse(value) => {
5471                super::AgentResponse::CloseSessionResponse(Box::new(value.into_v2()?))
5472            }
5473            Self::SetSessionModeResponse(_) => {
5474                return Err(removed_v1_enum_variant("AgentResponse", "session/set_mode"));
5475            }
5476            Self::SetSessionConfigOptionResponse(value) => {
5477                super::AgentResponse::SetSessionConfigOptionResponse(Box::new(value.into_v2()?))
5478            }
5479            Self::PromptResponse(value) => {
5480                super::AgentResponse::PromptResponse(Box::new(value.into_v2()?))
5481            }
5482            #[cfg(feature = "unstable_nes")]
5483            Self::StartNesResponse(value) => {
5484                super::AgentResponse::StartNesResponse(Box::new(value.into_v2()?))
5485            }
5486            #[cfg(feature = "unstable_nes")]
5487            Self::SuggestNesResponse(value) => {
5488                super::AgentResponse::SuggestNesResponse(Box::new(value.into_v2()?))
5489            }
5490            #[cfg(feature = "unstable_nes")]
5491            Self::CloseNesResponse(value) => {
5492                super::AgentResponse::CloseNesResponse(Box::new(value.into_v2()?))
5493            }
5494            Self::ExtMethodResponse(value) => {
5495                super::AgentResponse::ExtMethodResponse(Box::new(value.into_v2()?))
5496            }
5497            #[cfg(feature = "unstable_mcp_over_acp")]
5498            Self::MessageMcpResponse(value) => {
5499                super::AgentResponse::MessageMcpResponse(Box::new(value.into_v2()?))
5500            }
5501        })
5502    }
5503}
5504
5505impl IntoV1 for super::ClientNotification {
5506    type Output = crate::v1::ClientNotification;
5507
5508    fn into_v1(self) -> Result<Self::Output> {
5509        Ok(match self {
5510            Self::CancelSessionNotification(value) => {
5511                crate::v1::ClientNotification::CancelNotification(value.into_v1()?)
5512            }
5513            #[cfg(feature = "unstable_nes")]
5514            Self::DidOpenDocumentNotification(value) => {
5515                crate::v1::ClientNotification::DidOpenDocumentNotification(value.into_v1()?)
5516            }
5517            #[cfg(feature = "unstable_nes")]
5518            Self::DidChangeDocumentNotification(value) => {
5519                crate::v1::ClientNotification::DidChangeDocumentNotification(value.into_v1()?)
5520            }
5521            #[cfg(feature = "unstable_nes")]
5522            Self::DidCloseDocumentNotification(value) => {
5523                crate::v1::ClientNotification::DidCloseDocumentNotification(value.into_v1()?)
5524            }
5525            #[cfg(feature = "unstable_nes")]
5526            Self::DidSaveDocumentNotification(value) => {
5527                crate::v1::ClientNotification::DidSaveDocumentNotification(value.into_v1()?)
5528            }
5529            #[cfg(feature = "unstable_nes")]
5530            Self::DidFocusDocumentNotification(value) => {
5531                crate::v1::ClientNotification::DidFocusDocumentNotification(value.into_v1()?)
5532            }
5533            #[cfg(feature = "unstable_nes")]
5534            Self::AcceptNesNotification(value) => {
5535                crate::v1::ClientNotification::AcceptNesNotification(value.into_v1()?)
5536            }
5537            #[cfg(feature = "unstable_nes")]
5538            Self::RejectNesNotification(value) => {
5539                crate::v1::ClientNotification::RejectNesNotification(value.into_v1()?)
5540            }
5541            #[cfg(feature = "unstable_mcp_over_acp")]
5542            Self::MessageMcpNotification(value) => {
5543                crate::v1::ClientNotification::MessageMcpNotification(value.into_v1()?)
5544            }
5545            Self::ExtNotification(value) => {
5546                crate::v1::ClientNotification::ExtNotification(value.into_v1()?)
5547            }
5548        })
5549    }
5550}
5551
5552impl IntoV2 for crate::v1::ClientNotification {
5553    type Output = super::ClientNotification;
5554
5555    fn into_v2(self) -> Result<Self::Output> {
5556        Ok(match self {
5557            Self::CancelNotification(value) => {
5558                super::ClientNotification::CancelSessionNotification(Box::new(value.into_v2()?))
5559            }
5560            #[cfg(feature = "unstable_nes")]
5561            Self::DidOpenDocumentNotification(value) => {
5562                super::ClientNotification::DidOpenDocumentNotification(Box::new(value.into_v2()?))
5563            }
5564            #[cfg(feature = "unstable_nes")]
5565            Self::DidChangeDocumentNotification(value) => {
5566                super::ClientNotification::DidChangeDocumentNotification(Box::new(value.into_v2()?))
5567            }
5568            #[cfg(feature = "unstable_nes")]
5569            Self::DidCloseDocumentNotification(value) => {
5570                super::ClientNotification::DidCloseDocumentNotification(Box::new(value.into_v2()?))
5571            }
5572            #[cfg(feature = "unstable_nes")]
5573            Self::DidSaveDocumentNotification(value) => {
5574                super::ClientNotification::DidSaveDocumentNotification(Box::new(value.into_v2()?))
5575            }
5576            #[cfg(feature = "unstable_nes")]
5577            Self::DidFocusDocumentNotification(value) => {
5578                super::ClientNotification::DidFocusDocumentNotification(Box::new(value.into_v2()?))
5579            }
5580            #[cfg(feature = "unstable_nes")]
5581            Self::AcceptNesNotification(value) => {
5582                super::ClientNotification::AcceptNesNotification(Box::new(value.into_v2()?))
5583            }
5584            #[cfg(feature = "unstable_nes")]
5585            Self::RejectNesNotification(value) => {
5586                super::ClientNotification::RejectNesNotification(Box::new(value.into_v2()?))
5587            }
5588            #[cfg(feature = "unstable_mcp_over_acp")]
5589            Self::MessageMcpNotification(value) => {
5590                super::ClientNotification::MessageMcpNotification(Box::new(value.into_v2()?))
5591            }
5592            Self::ExtNotification(value) => {
5593                super::ClientNotification::ExtNotification(Box::new(value.into_v2()?))
5594            }
5595        })
5596    }
5597}
5598
5599impl IntoV1 for super::CancelSessionNotification {
5600    type Output = crate::v1::CancelNotification;
5601
5602    fn into_v1(self) -> Result<Self::Output> {
5603        let Self { session_id, meta } = self;
5604        Ok(crate::v1::CancelNotification {
5605            session_id: session_id.into_v1()?,
5606            meta: meta.into_v1()?,
5607        })
5608    }
5609}
5610
5611impl IntoV2 for crate::v1::CancelNotification {
5612    type Output = super::CancelSessionNotification;
5613
5614    fn into_v2(self) -> Result<Self::Output> {
5615        let Self { session_id, meta } = self;
5616        Ok(super::CancelSessionNotification {
5617            session_id: session_id.into_v2()?,
5618            meta: meta.into_v2()?,
5619        })
5620    }
5621}
5622
5623#[cfg(feature = "unstable_nes")]
5624impl IntoV1 for super::PositionEncodingKind {
5625    type Output = crate::v1::PositionEncodingKind;
5626
5627    fn into_v1(self) -> Result<Self::Output> {
5628        Ok(match self {
5629            Self::Utf16 => crate::v1::PositionEncodingKind::Utf16,
5630            Self::Utf32 => crate::v1::PositionEncodingKind::Utf32,
5631            Self::Utf8 => crate::v1::PositionEncodingKind::Utf8,
5632        })
5633    }
5634}
5635
5636#[cfg(feature = "unstable_nes")]
5637impl IntoV2 for crate::v1::PositionEncodingKind {
5638    type Output = super::PositionEncodingKind;
5639
5640    fn into_v2(self) -> Result<Self::Output> {
5641        Ok(match self {
5642            Self::Utf16 => super::PositionEncodingKind::Utf16,
5643            Self::Utf32 => super::PositionEncodingKind::Utf32,
5644            Self::Utf8 => super::PositionEncodingKind::Utf8,
5645        })
5646    }
5647}
5648
5649#[cfg(feature = "unstable_nes")]
5650impl IntoV1 for super::Position {
5651    type Output = crate::v1::Position;
5652
5653    fn into_v1(self) -> Result<Self::Output> {
5654        let Self {
5655            line,
5656            character,
5657            meta,
5658        } = self;
5659        Ok(crate::v1::Position {
5660            line: line.into_v1()?,
5661            character: character.into_v1()?,
5662            meta: meta.into_v1()?,
5663        })
5664    }
5665}
5666
5667#[cfg(feature = "unstable_nes")]
5668impl IntoV2 for crate::v1::Position {
5669    type Output = super::Position;
5670
5671    fn into_v2(self) -> Result<Self::Output> {
5672        let Self {
5673            line,
5674            character,
5675            meta,
5676        } = self;
5677        Ok(super::Position {
5678            line: line.into_v2()?,
5679            character: character.into_v2()?,
5680            meta: meta.into_v2()?,
5681        })
5682    }
5683}
5684
5685#[cfg(feature = "unstable_nes")]
5686impl IntoV1 for super::Range {
5687    type Output = crate::v1::Range;
5688
5689    fn into_v1(self) -> Result<Self::Output> {
5690        let Self { start, end, meta } = self;
5691        Ok(crate::v1::Range {
5692            start: start.into_v1()?,
5693            end: end.into_v1()?,
5694            meta: meta.into_v1()?,
5695        })
5696    }
5697}
5698
5699#[cfg(feature = "unstable_nes")]
5700impl IntoV2 for crate::v1::Range {
5701    type Output = super::Range;
5702
5703    fn into_v2(self) -> Result<Self::Output> {
5704        let Self { start, end, meta } = self;
5705        Ok(super::Range {
5706            start: start.into_v2()?,
5707            end: end.into_v2()?,
5708            meta: meta.into_v2()?,
5709        })
5710    }
5711}
5712
5713#[cfg(feature = "unstable_nes")]
5714impl IntoV1 for super::NesCapabilities {
5715    type Output = crate::v1::NesCapabilities;
5716
5717    fn into_v1(self) -> Result<Self::Output> {
5718        let Self {
5719            events,
5720            context,
5721            meta,
5722        } = self;
5723        Ok(crate::v1::NesCapabilities {
5724            events: into_v1_default_on_error(events),
5725            context: into_v1_default_on_error(context),
5726            meta: meta.into_v1()?,
5727        })
5728    }
5729}
5730
5731#[cfg(feature = "unstable_nes")]
5732impl IntoV2 for crate::v1::NesCapabilities {
5733    type Output = super::NesCapabilities;
5734
5735    fn into_v2(self) -> Result<Self::Output> {
5736        let Self {
5737            events,
5738            context,
5739            meta,
5740        } = self;
5741        Ok(super::NesCapabilities {
5742            events: into_v2_default_on_error(events),
5743            context: into_v2_default_on_error(context),
5744            meta: meta.into_v2()?,
5745        })
5746    }
5747}
5748
5749#[cfg(feature = "unstable_nes")]
5750impl IntoV1 for super::NesEventCapabilities {
5751    type Output = crate::v1::NesEventCapabilities;
5752
5753    fn into_v1(self) -> Result<Self::Output> {
5754        let Self { document, meta } = self;
5755        Ok(crate::v1::NesEventCapabilities {
5756            document: into_v1_default_on_error(document),
5757            meta: meta.into_v1()?,
5758        })
5759    }
5760}
5761
5762#[cfg(feature = "unstable_nes")]
5763impl IntoV2 for crate::v1::NesEventCapabilities {
5764    type Output = super::NesEventCapabilities;
5765
5766    fn into_v2(self) -> Result<Self::Output> {
5767        let Self { document, meta } = self;
5768        Ok(super::NesEventCapabilities {
5769            document: into_v2_default_on_error(document),
5770            meta: meta.into_v2()?,
5771        })
5772    }
5773}
5774
5775#[cfg(feature = "unstable_nes")]
5776impl IntoV1 for super::NesDocumentEventCapabilities {
5777    type Output = crate::v1::NesDocumentEventCapabilities;
5778
5779    fn into_v1(self) -> Result<Self::Output> {
5780        let Self {
5781            did_open,
5782            did_change,
5783            did_close,
5784            did_save,
5785            did_focus,
5786            meta,
5787        } = self;
5788        Ok(crate::v1::NesDocumentEventCapabilities {
5789            did_open: into_v1_default_on_error(did_open),
5790            did_change: into_v1_default_on_error(did_change),
5791            did_close: into_v1_default_on_error(did_close),
5792            did_save: into_v1_default_on_error(did_save),
5793            did_focus: into_v1_default_on_error(did_focus),
5794            meta: meta.into_v1()?,
5795        })
5796    }
5797}
5798
5799#[cfg(feature = "unstable_nes")]
5800impl IntoV2 for crate::v1::NesDocumentEventCapabilities {
5801    type Output = super::NesDocumentEventCapabilities;
5802
5803    fn into_v2(self) -> Result<Self::Output> {
5804        let Self {
5805            did_open,
5806            did_change,
5807            did_close,
5808            did_save,
5809            did_focus,
5810            meta,
5811        } = self;
5812        Ok(super::NesDocumentEventCapabilities {
5813            did_open: into_v2_default_on_error(did_open),
5814            did_change: into_v2_default_on_error(did_change),
5815            did_close: into_v2_default_on_error(did_close),
5816            did_save: into_v2_default_on_error(did_save),
5817            did_focus: into_v2_default_on_error(did_focus),
5818            meta: meta.into_v2()?,
5819        })
5820    }
5821}
5822
5823#[cfg(feature = "unstable_nes")]
5824impl IntoV1 for super::NesDocumentDidOpenCapabilities {
5825    type Output = crate::v1::NesDocumentDidOpenCapabilities;
5826
5827    fn into_v1(self) -> Result<Self::Output> {
5828        let Self { meta } = self;
5829        Ok(crate::v1::NesDocumentDidOpenCapabilities {
5830            meta: meta.into_v1()?,
5831        })
5832    }
5833}
5834
5835#[cfg(feature = "unstable_nes")]
5836impl IntoV2 for crate::v1::NesDocumentDidOpenCapabilities {
5837    type Output = super::NesDocumentDidOpenCapabilities;
5838
5839    fn into_v2(self) -> Result<Self::Output> {
5840        let Self { meta } = self;
5841        Ok(super::NesDocumentDidOpenCapabilities {
5842            meta: meta.into_v2()?,
5843        })
5844    }
5845}
5846
5847#[cfg(feature = "unstable_nes")]
5848impl IntoV1 for super::NesDocumentDidChangeCapabilities {
5849    type Output = crate::v1::NesDocumentDidChangeCapabilities;
5850
5851    fn into_v1(self) -> Result<Self::Output> {
5852        let Self { sync_kind, meta } = self;
5853        Ok(crate::v1::NesDocumentDidChangeCapabilities {
5854            sync_kind: sync_kind.into_v1()?,
5855            meta: meta.into_v1()?,
5856        })
5857    }
5858}
5859
5860#[cfg(feature = "unstable_nes")]
5861impl IntoV2 for crate::v1::NesDocumentDidChangeCapabilities {
5862    type Output = super::NesDocumentDidChangeCapabilities;
5863
5864    fn into_v2(self) -> Result<Self::Output> {
5865        let Self { sync_kind, meta } = self;
5866        Ok(super::NesDocumentDidChangeCapabilities {
5867            sync_kind: sync_kind.into_v2()?,
5868            meta: meta.into_v2()?,
5869        })
5870    }
5871}
5872
5873#[cfg(feature = "unstable_nes")]
5874impl IntoV1 for super::TextDocumentSyncKind {
5875    type Output = crate::v1::TextDocumentSyncKind;
5876
5877    fn into_v1(self) -> Result<Self::Output> {
5878        Ok(match self {
5879            Self::Full => crate::v1::TextDocumentSyncKind::Full,
5880            Self::Incremental => crate::v1::TextDocumentSyncKind::Incremental,
5881        })
5882    }
5883}
5884
5885#[cfg(feature = "unstable_nes")]
5886impl IntoV2 for crate::v1::TextDocumentSyncKind {
5887    type Output = super::TextDocumentSyncKind;
5888
5889    fn into_v2(self) -> Result<Self::Output> {
5890        Ok(match self {
5891            Self::Full => super::TextDocumentSyncKind::Full,
5892            Self::Incremental => super::TextDocumentSyncKind::Incremental,
5893        })
5894    }
5895}
5896
5897#[cfg(feature = "unstable_nes")]
5898impl IntoV1 for super::NesDocumentDidCloseCapabilities {
5899    type Output = crate::v1::NesDocumentDidCloseCapabilities;
5900
5901    fn into_v1(self) -> Result<Self::Output> {
5902        let Self { meta } = self;
5903        Ok(crate::v1::NesDocumentDidCloseCapabilities {
5904            meta: meta.into_v1()?,
5905        })
5906    }
5907}
5908
5909#[cfg(feature = "unstable_nes")]
5910impl IntoV2 for crate::v1::NesDocumentDidCloseCapabilities {
5911    type Output = super::NesDocumentDidCloseCapabilities;
5912
5913    fn into_v2(self) -> Result<Self::Output> {
5914        let Self { meta } = self;
5915        Ok(super::NesDocumentDidCloseCapabilities {
5916            meta: meta.into_v2()?,
5917        })
5918    }
5919}
5920
5921#[cfg(feature = "unstable_nes")]
5922impl IntoV1 for super::NesDocumentDidSaveCapabilities {
5923    type Output = crate::v1::NesDocumentDidSaveCapabilities;
5924
5925    fn into_v1(self) -> Result<Self::Output> {
5926        let Self { meta } = self;
5927        Ok(crate::v1::NesDocumentDidSaveCapabilities {
5928            meta: meta.into_v1()?,
5929        })
5930    }
5931}
5932
5933#[cfg(feature = "unstable_nes")]
5934impl IntoV2 for crate::v1::NesDocumentDidSaveCapabilities {
5935    type Output = super::NesDocumentDidSaveCapabilities;
5936
5937    fn into_v2(self) -> Result<Self::Output> {
5938        let Self { meta } = self;
5939        Ok(super::NesDocumentDidSaveCapabilities {
5940            meta: meta.into_v2()?,
5941        })
5942    }
5943}
5944
5945#[cfg(feature = "unstable_nes")]
5946impl IntoV1 for super::NesDocumentDidFocusCapabilities {
5947    type Output = crate::v1::NesDocumentDidFocusCapabilities;
5948
5949    fn into_v1(self) -> Result<Self::Output> {
5950        let Self { meta } = self;
5951        Ok(crate::v1::NesDocumentDidFocusCapabilities {
5952            meta: meta.into_v1()?,
5953        })
5954    }
5955}
5956
5957#[cfg(feature = "unstable_nes")]
5958impl IntoV2 for crate::v1::NesDocumentDidFocusCapabilities {
5959    type Output = super::NesDocumentDidFocusCapabilities;
5960
5961    fn into_v2(self) -> Result<Self::Output> {
5962        let Self { meta } = self;
5963        Ok(super::NesDocumentDidFocusCapabilities {
5964            meta: meta.into_v2()?,
5965        })
5966    }
5967}
5968
5969#[cfg(feature = "unstable_nes")]
5970impl IntoV1 for super::NesContextCapabilities {
5971    type Output = crate::v1::NesContextCapabilities;
5972
5973    fn into_v1(self) -> Result<Self::Output> {
5974        let Self {
5975            recent_files,
5976            related_snippets,
5977            edit_history,
5978            user_actions,
5979            open_files,
5980            diagnostics,
5981            meta,
5982        } = self;
5983        Ok(crate::v1::NesContextCapabilities {
5984            recent_files: into_v1_default_on_error(recent_files),
5985            related_snippets: into_v1_default_on_error(related_snippets),
5986            edit_history: into_v1_default_on_error(edit_history),
5987            user_actions: into_v1_default_on_error(user_actions),
5988            open_files: into_v1_default_on_error(open_files),
5989            diagnostics: into_v1_default_on_error(diagnostics),
5990            meta: meta.into_v1()?,
5991        })
5992    }
5993}
5994
5995#[cfg(feature = "unstable_nes")]
5996impl IntoV2 for crate::v1::NesContextCapabilities {
5997    type Output = super::NesContextCapabilities;
5998
5999    fn into_v2(self) -> Result<Self::Output> {
6000        let Self {
6001            recent_files,
6002            related_snippets,
6003            edit_history,
6004            user_actions,
6005            open_files,
6006            diagnostics,
6007            meta,
6008        } = self;
6009        Ok(super::NesContextCapabilities {
6010            recent_files: into_v2_default_on_error(recent_files),
6011            related_snippets: into_v2_default_on_error(related_snippets),
6012            edit_history: into_v2_default_on_error(edit_history),
6013            user_actions: into_v2_default_on_error(user_actions),
6014            open_files: into_v2_default_on_error(open_files),
6015            diagnostics: into_v2_default_on_error(diagnostics),
6016            meta: meta.into_v2()?,
6017        })
6018    }
6019}
6020
6021#[cfg(feature = "unstable_nes")]
6022impl IntoV1 for super::NesRecentFilesCapabilities {
6023    type Output = crate::v1::NesRecentFilesCapabilities;
6024
6025    fn into_v1(self) -> Result<Self::Output> {
6026        let Self { max_count, meta } = self;
6027        Ok(crate::v1::NesRecentFilesCapabilities {
6028            max_count: max_count.into_v1()?,
6029            meta: meta.into_v1()?,
6030        })
6031    }
6032}
6033
6034#[cfg(feature = "unstable_nes")]
6035impl IntoV2 for crate::v1::NesRecentFilesCapabilities {
6036    type Output = super::NesRecentFilesCapabilities;
6037
6038    fn into_v2(self) -> Result<Self::Output> {
6039        let Self { max_count, meta } = self;
6040        Ok(super::NesRecentFilesCapabilities {
6041            max_count: max_count.into_v2()?,
6042            meta: meta.into_v2()?,
6043        })
6044    }
6045}
6046
6047#[cfg(feature = "unstable_nes")]
6048impl IntoV1 for super::NesRelatedSnippetsCapabilities {
6049    type Output = crate::v1::NesRelatedSnippetsCapabilities;
6050
6051    fn into_v1(self) -> Result<Self::Output> {
6052        let Self { meta } = self;
6053        Ok(crate::v1::NesRelatedSnippetsCapabilities {
6054            meta: meta.into_v1()?,
6055        })
6056    }
6057}
6058
6059#[cfg(feature = "unstable_nes")]
6060impl IntoV2 for crate::v1::NesRelatedSnippetsCapabilities {
6061    type Output = super::NesRelatedSnippetsCapabilities;
6062
6063    fn into_v2(self) -> Result<Self::Output> {
6064        let Self { meta } = self;
6065        Ok(super::NesRelatedSnippetsCapabilities {
6066            meta: meta.into_v2()?,
6067        })
6068    }
6069}
6070
6071#[cfg(feature = "unstable_nes")]
6072impl IntoV1 for super::NesEditHistoryCapabilities {
6073    type Output = crate::v1::NesEditHistoryCapabilities;
6074
6075    fn into_v1(self) -> Result<Self::Output> {
6076        let Self { max_count, meta } = self;
6077        Ok(crate::v1::NesEditHistoryCapabilities {
6078            max_count: max_count.into_v1()?,
6079            meta: meta.into_v1()?,
6080        })
6081    }
6082}
6083
6084#[cfg(feature = "unstable_nes")]
6085impl IntoV2 for crate::v1::NesEditHistoryCapabilities {
6086    type Output = super::NesEditHistoryCapabilities;
6087
6088    fn into_v2(self) -> Result<Self::Output> {
6089        let Self { max_count, meta } = self;
6090        Ok(super::NesEditHistoryCapabilities {
6091            max_count: max_count.into_v2()?,
6092            meta: meta.into_v2()?,
6093        })
6094    }
6095}
6096
6097#[cfg(feature = "unstable_nes")]
6098impl IntoV1 for super::NesUserActionsCapabilities {
6099    type Output = crate::v1::NesUserActionsCapabilities;
6100
6101    fn into_v1(self) -> Result<Self::Output> {
6102        let Self { max_count, meta } = self;
6103        Ok(crate::v1::NesUserActionsCapabilities {
6104            max_count: max_count.into_v1()?,
6105            meta: meta.into_v1()?,
6106        })
6107    }
6108}
6109
6110#[cfg(feature = "unstable_nes")]
6111impl IntoV2 for crate::v1::NesUserActionsCapabilities {
6112    type Output = super::NesUserActionsCapabilities;
6113
6114    fn into_v2(self) -> Result<Self::Output> {
6115        let Self { max_count, meta } = self;
6116        Ok(super::NesUserActionsCapabilities {
6117            max_count: max_count.into_v2()?,
6118            meta: meta.into_v2()?,
6119        })
6120    }
6121}
6122
6123#[cfg(feature = "unstable_nes")]
6124impl IntoV1 for super::NesOpenFilesCapabilities {
6125    type Output = crate::v1::NesOpenFilesCapabilities;
6126
6127    fn into_v1(self) -> Result<Self::Output> {
6128        let Self { meta } = self;
6129        Ok(crate::v1::NesOpenFilesCapabilities {
6130            meta: meta.into_v1()?,
6131        })
6132    }
6133}
6134
6135#[cfg(feature = "unstable_nes")]
6136impl IntoV2 for crate::v1::NesOpenFilesCapabilities {
6137    type Output = super::NesOpenFilesCapabilities;
6138
6139    fn into_v2(self) -> Result<Self::Output> {
6140        let Self { meta } = self;
6141        Ok(super::NesOpenFilesCapabilities {
6142            meta: meta.into_v2()?,
6143        })
6144    }
6145}
6146
6147#[cfg(feature = "unstable_nes")]
6148impl IntoV1 for super::NesDiagnosticsCapabilities {
6149    type Output = crate::v1::NesDiagnosticsCapabilities;
6150
6151    fn into_v1(self) -> Result<Self::Output> {
6152        let Self { meta } = self;
6153        Ok(crate::v1::NesDiagnosticsCapabilities {
6154            meta: meta.into_v1()?,
6155        })
6156    }
6157}
6158
6159#[cfg(feature = "unstable_nes")]
6160impl IntoV2 for crate::v1::NesDiagnosticsCapabilities {
6161    type Output = super::NesDiagnosticsCapabilities;
6162
6163    fn into_v2(self) -> Result<Self::Output> {
6164        let Self { meta } = self;
6165        Ok(super::NesDiagnosticsCapabilities {
6166            meta: meta.into_v2()?,
6167        })
6168    }
6169}
6170
6171#[cfg(feature = "unstable_nes")]
6172impl IntoV1 for super::ClientNesCapabilities {
6173    type Output = crate::v1::ClientNesCapabilities;
6174
6175    fn into_v1(self) -> Result<Self::Output> {
6176        let Self {
6177            jump,
6178            rename,
6179            search_and_replace,
6180            meta,
6181        } = self;
6182        Ok(crate::v1::ClientNesCapabilities {
6183            jump: into_v1_default_on_error(jump),
6184            rename: into_v1_default_on_error(rename),
6185            search_and_replace: into_v1_default_on_error(search_and_replace),
6186            meta: meta.into_v1()?,
6187        })
6188    }
6189}
6190
6191#[cfg(feature = "unstable_nes")]
6192impl IntoV2 for crate::v1::ClientNesCapabilities {
6193    type Output = super::ClientNesCapabilities;
6194
6195    fn into_v2(self) -> Result<Self::Output> {
6196        let Self {
6197            jump,
6198            rename,
6199            search_and_replace,
6200            meta,
6201        } = self;
6202        Ok(super::ClientNesCapabilities {
6203            jump: into_v2_default_on_error(jump),
6204            rename: into_v2_default_on_error(rename),
6205            search_and_replace: into_v2_default_on_error(search_and_replace),
6206            meta: meta.into_v2()?,
6207        })
6208    }
6209}
6210
6211#[cfg(feature = "unstable_nes")]
6212impl IntoV1 for super::NesJumpCapabilities {
6213    type Output = crate::v1::NesJumpCapabilities;
6214
6215    fn into_v1(self) -> Result<Self::Output> {
6216        let Self { meta } = self;
6217        Ok(crate::v1::NesJumpCapabilities {
6218            meta: meta.into_v1()?,
6219        })
6220    }
6221}
6222
6223#[cfg(feature = "unstable_nes")]
6224impl IntoV2 for crate::v1::NesJumpCapabilities {
6225    type Output = super::NesJumpCapabilities;
6226
6227    fn into_v2(self) -> Result<Self::Output> {
6228        let Self { meta } = self;
6229        Ok(super::NesJumpCapabilities {
6230            meta: meta.into_v2()?,
6231        })
6232    }
6233}
6234
6235#[cfg(feature = "unstable_nes")]
6236impl IntoV1 for super::NesRenameCapabilities {
6237    type Output = crate::v1::NesRenameCapabilities;
6238
6239    fn into_v1(self) -> Result<Self::Output> {
6240        let Self { meta } = self;
6241        Ok(crate::v1::NesRenameCapabilities {
6242            meta: meta.into_v1()?,
6243        })
6244    }
6245}
6246
6247#[cfg(feature = "unstable_nes")]
6248impl IntoV2 for crate::v1::NesRenameCapabilities {
6249    type Output = super::NesRenameCapabilities;
6250
6251    fn into_v2(self) -> Result<Self::Output> {
6252        let Self { meta } = self;
6253        Ok(super::NesRenameCapabilities {
6254            meta: meta.into_v2()?,
6255        })
6256    }
6257}
6258
6259#[cfg(feature = "unstable_nes")]
6260impl IntoV1 for super::NesSearchAndReplaceCapabilities {
6261    type Output = crate::v1::NesSearchAndReplaceCapabilities;
6262
6263    fn into_v1(self) -> Result<Self::Output> {
6264        let Self { meta } = self;
6265        Ok(crate::v1::NesSearchAndReplaceCapabilities {
6266            meta: meta.into_v1()?,
6267        })
6268    }
6269}
6270
6271#[cfg(feature = "unstable_nes")]
6272impl IntoV2 for crate::v1::NesSearchAndReplaceCapabilities {
6273    type Output = super::NesSearchAndReplaceCapabilities;
6274
6275    fn into_v2(self) -> Result<Self::Output> {
6276        let Self { meta } = self;
6277        Ok(super::NesSearchAndReplaceCapabilities {
6278            meta: meta.into_v2()?,
6279        })
6280    }
6281}
6282
6283#[cfg(feature = "unstable_nes")]
6284impl IntoV1 for super::DidOpenDocumentNotification {
6285    type Output = crate::v1::DidOpenDocumentNotification;
6286
6287    fn into_v1(self) -> Result<Self::Output> {
6288        let Self {
6289            session_id,
6290            uri,
6291            language_id,
6292            version,
6293            text,
6294            meta,
6295        } = self;
6296        Ok(crate::v1::DidOpenDocumentNotification {
6297            session_id: session_id.into_v1()?,
6298            uri: uri.into_v1()?,
6299            language_id: language_id.into_v1()?,
6300            version: version.into_v1()?,
6301            text: text.into_v1()?,
6302            meta: meta.into_v1()?,
6303        })
6304    }
6305}
6306
6307#[cfg(feature = "unstable_nes")]
6308impl IntoV2 for crate::v1::DidOpenDocumentNotification {
6309    type Output = super::DidOpenDocumentNotification;
6310
6311    fn into_v2(self) -> Result<Self::Output> {
6312        let Self {
6313            session_id,
6314            uri,
6315            language_id,
6316            version,
6317            text,
6318            meta,
6319        } = self;
6320        Ok(super::DidOpenDocumentNotification {
6321            session_id: session_id.into_v2()?,
6322            uri: uri.into_v2()?,
6323            language_id: language_id.into_v2()?,
6324            version: version.into_v2()?,
6325            text: text.into_v2()?,
6326            meta: meta.into_v2()?,
6327        })
6328    }
6329}
6330
6331#[cfg(feature = "unstable_nes")]
6332impl IntoV1 for super::DidChangeDocumentNotification {
6333    type Output = crate::v1::DidChangeDocumentNotification;
6334
6335    fn into_v1(self) -> Result<Self::Output> {
6336        let Self {
6337            session_id,
6338            uri,
6339            version,
6340            content_changes,
6341            meta,
6342        } = self;
6343        Ok(crate::v1::DidChangeDocumentNotification {
6344            session_id: session_id.into_v1()?,
6345            uri: uri.into_v1()?,
6346            version: version.into_v1()?,
6347            content_changes: content_changes.into_v1()?,
6348            meta: meta.into_v1()?,
6349        })
6350    }
6351}
6352
6353#[cfg(feature = "unstable_nes")]
6354impl IntoV2 for crate::v1::DidChangeDocumentNotification {
6355    type Output = super::DidChangeDocumentNotification;
6356
6357    fn into_v2(self) -> Result<Self::Output> {
6358        let Self {
6359            session_id,
6360            uri,
6361            version,
6362            content_changes,
6363            meta,
6364        } = self;
6365        Ok(super::DidChangeDocumentNotification {
6366            session_id: session_id.into_v2()?,
6367            uri: uri.into_v2()?,
6368            version: version.into_v2()?,
6369            content_changes: content_changes.into_v2()?,
6370            meta: meta.into_v2()?,
6371        })
6372    }
6373}
6374
6375#[cfg(feature = "unstable_nes")]
6376impl IntoV1 for super::TextDocumentContentChangeEvent {
6377    type Output = crate::v1::TextDocumentContentChangeEvent;
6378
6379    fn into_v1(self) -> Result<Self::Output> {
6380        let Self { range, text, meta } = self;
6381        Ok(crate::v1::TextDocumentContentChangeEvent {
6382            range: range.into_v1()?,
6383            text: text.into_v1()?,
6384            meta: meta.into_v1()?,
6385        })
6386    }
6387}
6388
6389#[cfg(feature = "unstable_nes")]
6390impl IntoV2 for crate::v1::TextDocumentContentChangeEvent {
6391    type Output = super::TextDocumentContentChangeEvent;
6392
6393    fn into_v2(self) -> Result<Self::Output> {
6394        let Self { range, text, meta } = self;
6395        Ok(super::TextDocumentContentChangeEvent {
6396            range: range.into_v2()?,
6397            text: text.into_v2()?,
6398            meta: meta.into_v2()?,
6399        })
6400    }
6401}
6402
6403#[cfg(feature = "unstable_nes")]
6404impl IntoV1 for super::DidCloseDocumentNotification {
6405    type Output = crate::v1::DidCloseDocumentNotification;
6406
6407    fn into_v1(self) -> Result<Self::Output> {
6408        let Self {
6409            session_id,
6410            uri,
6411            meta,
6412        } = self;
6413        Ok(crate::v1::DidCloseDocumentNotification {
6414            session_id: session_id.into_v1()?,
6415            uri: uri.into_v1()?,
6416            meta: meta.into_v1()?,
6417        })
6418    }
6419}
6420
6421#[cfg(feature = "unstable_nes")]
6422impl IntoV2 for crate::v1::DidCloseDocumentNotification {
6423    type Output = super::DidCloseDocumentNotification;
6424
6425    fn into_v2(self) -> Result<Self::Output> {
6426        let Self {
6427            session_id,
6428            uri,
6429            meta,
6430        } = self;
6431        Ok(super::DidCloseDocumentNotification {
6432            session_id: session_id.into_v2()?,
6433            uri: uri.into_v2()?,
6434            meta: meta.into_v2()?,
6435        })
6436    }
6437}
6438
6439#[cfg(feature = "unstable_nes")]
6440impl IntoV1 for super::DidSaveDocumentNotification {
6441    type Output = crate::v1::DidSaveDocumentNotification;
6442
6443    fn into_v1(self) -> Result<Self::Output> {
6444        let Self {
6445            session_id,
6446            uri,
6447            meta,
6448        } = self;
6449        Ok(crate::v1::DidSaveDocumentNotification {
6450            session_id: session_id.into_v1()?,
6451            uri: uri.into_v1()?,
6452            meta: meta.into_v1()?,
6453        })
6454    }
6455}
6456
6457#[cfg(feature = "unstable_nes")]
6458impl IntoV2 for crate::v1::DidSaveDocumentNotification {
6459    type Output = super::DidSaveDocumentNotification;
6460
6461    fn into_v2(self) -> Result<Self::Output> {
6462        let Self {
6463            session_id,
6464            uri,
6465            meta,
6466        } = self;
6467        Ok(super::DidSaveDocumentNotification {
6468            session_id: session_id.into_v2()?,
6469            uri: uri.into_v2()?,
6470            meta: meta.into_v2()?,
6471        })
6472    }
6473}
6474
6475#[cfg(feature = "unstable_nes")]
6476impl IntoV1 for super::DidFocusDocumentNotification {
6477    type Output = crate::v1::DidFocusDocumentNotification;
6478
6479    fn into_v1(self) -> Result<Self::Output> {
6480        let Self {
6481            session_id,
6482            uri,
6483            version,
6484            position,
6485            visible_range,
6486            meta,
6487        } = self;
6488        Ok(crate::v1::DidFocusDocumentNotification {
6489            session_id: session_id.into_v1()?,
6490            uri: uri.into_v1()?,
6491            version: version.into_v1()?,
6492            position: position.into_v1()?,
6493            visible_range: visible_range.into_v1()?,
6494            meta: meta.into_v1()?,
6495        })
6496    }
6497}
6498
6499#[cfg(feature = "unstable_nes")]
6500impl IntoV2 for crate::v1::DidFocusDocumentNotification {
6501    type Output = super::DidFocusDocumentNotification;
6502
6503    fn into_v2(self) -> Result<Self::Output> {
6504        let Self {
6505            session_id,
6506            uri,
6507            version,
6508            position,
6509            visible_range,
6510            meta,
6511        } = self;
6512        Ok(super::DidFocusDocumentNotification {
6513            session_id: session_id.into_v2()?,
6514            uri: uri.into_v2()?,
6515            version: version.into_v2()?,
6516            position: position.into_v2()?,
6517            visible_range: visible_range.into_v2()?,
6518            meta: meta.into_v2()?,
6519        })
6520    }
6521}
6522
6523#[cfg(feature = "unstable_nes")]
6524impl IntoV1 for super::StartNesRequest {
6525    type Output = crate::v1::StartNesRequest;
6526
6527    fn into_v1(self) -> Result<Self::Output> {
6528        let Self {
6529            workspace_uri,
6530            workspace_folders,
6531            repository,
6532            meta,
6533        } = self;
6534        Ok(crate::v1::StartNesRequest {
6535            workspace_uri: workspace_uri.into_v1()?,
6536            workspace_folders: option_vec_into_v1_skip_errors(workspace_folders),
6537            repository: into_v1_default_on_error(repository),
6538            meta: meta.into_v1()?,
6539        })
6540    }
6541}
6542
6543#[cfg(feature = "unstable_nes")]
6544impl IntoV2 for crate::v1::StartNesRequest {
6545    type Output = super::StartNesRequest;
6546
6547    fn into_v2(self) -> Result<Self::Output> {
6548        let Self {
6549            workspace_uri,
6550            workspace_folders,
6551            repository,
6552            meta,
6553        } = self;
6554        Ok(super::StartNesRequest {
6555            workspace_uri: workspace_uri.into_v2()?,
6556            workspace_folders: option_vec_into_v2_skip_errors(workspace_folders),
6557            repository: into_v2_default_on_error(repository),
6558            meta: meta.into_v2()?,
6559        })
6560    }
6561}
6562
6563#[cfg(feature = "unstable_nes")]
6564impl IntoV1 for super::WorkspaceFolder {
6565    type Output = crate::v1::WorkspaceFolder;
6566
6567    fn into_v1(self) -> Result<Self::Output> {
6568        let Self { uri, name, meta } = self;
6569        Ok(crate::v1::WorkspaceFolder {
6570            uri: uri.into_v1()?,
6571            name: name.into_v1()?,
6572            meta: meta.into_v1()?,
6573        })
6574    }
6575}
6576
6577#[cfg(feature = "unstable_nes")]
6578impl IntoV2 for crate::v1::WorkspaceFolder {
6579    type Output = super::WorkspaceFolder;
6580
6581    fn into_v2(self) -> Result<Self::Output> {
6582        let Self { uri, name, meta } = self;
6583        Ok(super::WorkspaceFolder {
6584            uri: uri.into_v2()?,
6585            name: name.into_v2()?,
6586            meta: meta.into_v2()?,
6587        })
6588    }
6589}
6590
6591#[cfg(feature = "unstable_nes")]
6592impl IntoV1 for super::NesRepository {
6593    type Output = crate::v1::NesRepository;
6594
6595    fn into_v1(self) -> Result<Self::Output> {
6596        let Self {
6597            name,
6598            owner,
6599            remote_url,
6600            meta,
6601        } = self;
6602        Ok(crate::v1::NesRepository {
6603            name: name.into_v1()?,
6604            owner: owner.into_v1()?,
6605            remote_url: remote_url.into_v1()?,
6606            meta: meta.into_v1()?,
6607        })
6608    }
6609}
6610
6611#[cfg(feature = "unstable_nes")]
6612impl IntoV2 for crate::v1::NesRepository {
6613    type Output = super::NesRepository;
6614
6615    fn into_v2(self) -> Result<Self::Output> {
6616        let Self {
6617            name,
6618            owner,
6619            remote_url,
6620            meta,
6621        } = self;
6622        Ok(super::NesRepository {
6623            name: name.into_v2()?,
6624            owner: owner.into_v2()?,
6625            remote_url: remote_url.into_v2()?,
6626            meta: meta.into_v2()?,
6627        })
6628    }
6629}
6630
6631#[cfg(feature = "unstable_nes")]
6632impl IntoV1 for super::StartNesResponse {
6633    type Output = crate::v1::StartNesResponse;
6634
6635    fn into_v1(self) -> Result<Self::Output> {
6636        let Self { session_id, meta } = self;
6637        Ok(crate::v1::StartNesResponse {
6638            session_id: session_id.into_v1()?,
6639            meta: meta.into_v1()?,
6640        })
6641    }
6642}
6643
6644#[cfg(feature = "unstable_nes")]
6645impl IntoV2 for crate::v1::StartNesResponse {
6646    type Output = super::StartNesResponse;
6647
6648    fn into_v2(self) -> Result<Self::Output> {
6649        let Self { session_id, meta } = self;
6650        Ok(super::StartNesResponse {
6651            session_id: session_id.into_v2()?,
6652            meta: meta.into_v2()?,
6653        })
6654    }
6655}
6656
6657#[cfg(feature = "unstable_nes")]
6658impl IntoV1 for super::CloseNesRequest {
6659    type Output = crate::v1::CloseNesRequest;
6660
6661    fn into_v1(self) -> Result<Self::Output> {
6662        let Self { session_id, meta } = self;
6663        Ok(crate::v1::CloseNesRequest {
6664            session_id: session_id.into_v1()?,
6665            meta: meta.into_v1()?,
6666        })
6667    }
6668}
6669
6670#[cfg(feature = "unstable_nes")]
6671impl IntoV2 for crate::v1::CloseNesRequest {
6672    type Output = super::CloseNesRequest;
6673
6674    fn into_v2(self) -> Result<Self::Output> {
6675        let Self { session_id, meta } = self;
6676        Ok(super::CloseNesRequest {
6677            session_id: session_id.into_v2()?,
6678            meta: meta.into_v2()?,
6679        })
6680    }
6681}
6682
6683#[cfg(feature = "unstable_nes")]
6684impl IntoV1 for super::CloseNesResponse {
6685    type Output = crate::v1::CloseNesResponse;
6686
6687    fn into_v1(self) -> Result<Self::Output> {
6688        let Self { meta } = self;
6689        Ok(crate::v1::CloseNesResponse {
6690            meta: meta.into_v1()?,
6691        })
6692    }
6693}
6694
6695#[cfg(feature = "unstable_nes")]
6696impl IntoV2 for crate::v1::CloseNesResponse {
6697    type Output = super::CloseNesResponse;
6698
6699    fn into_v2(self) -> Result<Self::Output> {
6700        let Self { meta } = self;
6701        Ok(super::CloseNesResponse {
6702            meta: meta.into_v2()?,
6703        })
6704    }
6705}
6706
6707#[cfg(feature = "unstable_nes")]
6708impl IntoV1 for super::NesTriggerKind {
6709    type Output = crate::v1::NesTriggerKind;
6710
6711    fn into_v1(self) -> Result<Self::Output> {
6712        Ok(match self {
6713            Self::Automatic => crate::v1::NesTriggerKind::Automatic,
6714            Self::Diagnostic => crate::v1::NesTriggerKind::Diagnostic,
6715            Self::Manual => crate::v1::NesTriggerKind::Manual,
6716            Self::Other(value) => return Err(unknown_v2_enum_variant("NesTriggerKind", &value)),
6717        })
6718    }
6719}
6720
6721#[cfg(feature = "unstable_nes")]
6722impl IntoV2 for crate::v1::NesTriggerKind {
6723    type Output = super::NesTriggerKind;
6724
6725    fn into_v2(self) -> Result<Self::Output> {
6726        Ok(match self {
6727            Self::Automatic => super::NesTriggerKind::Automatic,
6728            Self::Diagnostic => super::NesTriggerKind::Diagnostic,
6729            Self::Manual => super::NesTriggerKind::Manual,
6730        })
6731    }
6732}
6733
6734#[cfg(feature = "unstable_nes")]
6735impl IntoV1 for super::SuggestNesRequest {
6736    type Output = crate::v1::SuggestNesRequest;
6737
6738    fn into_v1(self) -> Result<Self::Output> {
6739        let Self {
6740            session_id,
6741            uri,
6742            version,
6743            position,
6744            selection,
6745            trigger_kind,
6746            context,
6747            meta,
6748        } = self;
6749        Ok(crate::v1::SuggestNesRequest {
6750            session_id: session_id.into_v1()?,
6751            uri: uri.into_v1()?,
6752            version: version.into_v1()?,
6753            position: position.into_v1()?,
6754            selection: into_v1_default_on_error(selection),
6755            trigger_kind: trigger_kind.into_v1()?,
6756            context: into_v1_default_on_error(context),
6757            meta: meta.into_v1()?,
6758        })
6759    }
6760}
6761
6762#[cfg(feature = "unstable_nes")]
6763impl IntoV2 for crate::v1::SuggestNesRequest {
6764    type Output = super::SuggestNesRequest;
6765
6766    fn into_v2(self) -> Result<Self::Output> {
6767        let Self {
6768            session_id,
6769            uri,
6770            version,
6771            position,
6772            selection,
6773            trigger_kind,
6774            context,
6775            meta,
6776        } = self;
6777        Ok(super::SuggestNesRequest {
6778            session_id: session_id.into_v2()?,
6779            uri: uri.into_v2()?,
6780            version: version.into_v2()?,
6781            position: position.into_v2()?,
6782            selection: into_v2_default_on_error(selection),
6783            trigger_kind: trigger_kind.into_v2()?,
6784            context: into_v2_default_on_error(context),
6785            meta: meta.into_v2()?,
6786        })
6787    }
6788}
6789
6790#[cfg(feature = "unstable_nes")]
6791impl IntoV1 for super::NesSuggestContext {
6792    type Output = crate::v1::NesSuggestContext;
6793
6794    fn into_v1(self) -> Result<Self::Output> {
6795        let Self {
6796            recent_files,
6797            related_snippets,
6798            edit_history,
6799            user_actions,
6800            open_files,
6801            diagnostics,
6802            meta,
6803        } = self;
6804        Ok(crate::v1::NesSuggestContext {
6805            recent_files: option_vec_into_v1_skip_errors(recent_files),
6806            related_snippets: option_vec_into_v1_skip_errors(related_snippets),
6807            edit_history: option_vec_into_v1_skip_errors(edit_history),
6808            user_actions: option_vec_into_v1_skip_errors(user_actions),
6809            open_files: option_vec_into_v1_skip_errors(open_files),
6810            diagnostics: option_vec_into_v1_skip_errors(diagnostics),
6811            meta: meta.into_v1()?,
6812        })
6813    }
6814}
6815
6816#[cfg(feature = "unstable_nes")]
6817impl IntoV2 for crate::v1::NesSuggestContext {
6818    type Output = super::NesSuggestContext;
6819
6820    fn into_v2(self) -> Result<Self::Output> {
6821        let Self {
6822            recent_files,
6823            related_snippets,
6824            edit_history,
6825            user_actions,
6826            open_files,
6827            diagnostics,
6828            meta,
6829        } = self;
6830        Ok(super::NesSuggestContext {
6831            recent_files: option_vec_into_v2_skip_errors(recent_files),
6832            related_snippets: option_vec_into_v2_skip_errors(related_snippets),
6833            edit_history: option_vec_into_v2_skip_errors(edit_history),
6834            user_actions: option_vec_into_v2_skip_errors(user_actions),
6835            open_files: option_vec_into_v2_skip_errors(open_files),
6836            diagnostics: option_vec_into_v2_skip_errors(diagnostics),
6837            meta: meta.into_v2()?,
6838        })
6839    }
6840}
6841
6842#[cfg(feature = "unstable_nes")]
6843impl IntoV1 for super::NesRecentFile {
6844    type Output = crate::v1::NesRecentFile;
6845
6846    fn into_v1(self) -> Result<Self::Output> {
6847        let Self {
6848            uri,
6849            language_id,
6850            text,
6851            meta,
6852        } = self;
6853        Ok(crate::v1::NesRecentFile {
6854            uri: uri.into_v1()?,
6855            language_id: language_id.into_v1()?,
6856            text: text.into_v1()?,
6857            meta: meta.into_v1()?,
6858        })
6859    }
6860}
6861
6862#[cfg(feature = "unstable_nes")]
6863impl IntoV2 for crate::v1::NesRecentFile {
6864    type Output = super::NesRecentFile;
6865
6866    fn into_v2(self) -> Result<Self::Output> {
6867        let Self {
6868            uri,
6869            language_id,
6870            text,
6871            meta,
6872        } = self;
6873        Ok(super::NesRecentFile {
6874            uri: uri.into_v2()?,
6875            language_id: language_id.into_v2()?,
6876            text: text.into_v2()?,
6877            meta: meta.into_v2()?,
6878        })
6879    }
6880}
6881
6882#[cfg(feature = "unstable_nes")]
6883impl IntoV1 for super::NesRelatedSnippet {
6884    type Output = crate::v1::NesRelatedSnippet;
6885
6886    fn into_v1(self) -> Result<Self::Output> {
6887        let Self {
6888            uri,
6889            excerpts,
6890            meta,
6891        } = self;
6892        Ok(crate::v1::NesRelatedSnippet {
6893            uri: uri.into_v1()?,
6894            excerpts: excerpts.into_v1()?,
6895            meta: meta.into_v1()?,
6896        })
6897    }
6898}
6899
6900#[cfg(feature = "unstable_nes")]
6901impl IntoV2 for crate::v1::NesRelatedSnippet {
6902    type Output = super::NesRelatedSnippet;
6903
6904    fn into_v2(self) -> Result<Self::Output> {
6905        let Self {
6906            uri,
6907            excerpts,
6908            meta,
6909        } = self;
6910        Ok(super::NesRelatedSnippet {
6911            uri: uri.into_v2()?,
6912            excerpts: excerpts.into_v2()?,
6913            meta: meta.into_v2()?,
6914        })
6915    }
6916}
6917
6918#[cfg(feature = "unstable_nes")]
6919impl IntoV1 for super::NesExcerpt {
6920    type Output = crate::v1::NesExcerpt;
6921
6922    fn into_v1(self) -> Result<Self::Output> {
6923        let Self {
6924            start_line,
6925            end_line,
6926            text,
6927            meta,
6928        } = self;
6929        Ok(crate::v1::NesExcerpt {
6930            start_line: start_line.into_v1()?,
6931            end_line: end_line.into_v1()?,
6932            text: text.into_v1()?,
6933            meta: meta.into_v1()?,
6934        })
6935    }
6936}
6937
6938#[cfg(feature = "unstable_nes")]
6939impl IntoV2 for crate::v1::NesExcerpt {
6940    type Output = super::NesExcerpt;
6941
6942    fn into_v2(self) -> Result<Self::Output> {
6943        let Self {
6944            start_line,
6945            end_line,
6946            text,
6947            meta,
6948        } = self;
6949        Ok(super::NesExcerpt {
6950            start_line: start_line.into_v2()?,
6951            end_line: end_line.into_v2()?,
6952            text: text.into_v2()?,
6953            meta: meta.into_v2()?,
6954        })
6955    }
6956}
6957
6958#[cfg(feature = "unstable_nes")]
6959impl IntoV1 for super::NesEditHistoryEntry {
6960    type Output = crate::v1::NesEditHistoryEntry;
6961
6962    fn into_v1(self) -> Result<Self::Output> {
6963        let Self { uri, diff, meta } = self;
6964        Ok(crate::v1::NesEditHistoryEntry {
6965            uri: uri.into_v1()?,
6966            diff: diff.into_v1()?,
6967            meta: meta.into_v1()?,
6968        })
6969    }
6970}
6971
6972#[cfg(feature = "unstable_nes")]
6973impl IntoV2 for crate::v1::NesEditHistoryEntry {
6974    type Output = super::NesEditHistoryEntry;
6975
6976    fn into_v2(self) -> Result<Self::Output> {
6977        let Self { uri, diff, meta } = self;
6978        Ok(super::NesEditHistoryEntry {
6979            uri: uri.into_v2()?,
6980            diff: diff.into_v2()?,
6981            meta: meta.into_v2()?,
6982        })
6983    }
6984}
6985
6986#[cfg(feature = "unstable_nes")]
6987impl IntoV1 for super::NesUserAction {
6988    type Output = crate::v1::NesUserAction;
6989
6990    fn into_v1(self) -> Result<Self::Output> {
6991        let Self {
6992            action,
6993            uri,
6994            position,
6995            timestamp_ms,
6996            meta,
6997        } = self;
6998        Ok(crate::v1::NesUserAction {
6999            action: action.into_v1()?,
7000            uri: uri.into_v1()?,
7001            position: position.into_v1()?,
7002            timestamp_ms: timestamp_ms.into_v1()?,
7003            meta: meta.into_v1()?,
7004        })
7005    }
7006}
7007
7008#[cfg(feature = "unstable_nes")]
7009impl IntoV2 for crate::v1::NesUserAction {
7010    type Output = super::NesUserAction;
7011
7012    fn into_v2(self) -> Result<Self::Output> {
7013        let Self {
7014            action,
7015            uri,
7016            position,
7017            timestamp_ms,
7018            meta,
7019        } = self;
7020        Ok(super::NesUserAction {
7021            action: action.into_v2()?,
7022            uri: uri.into_v2()?,
7023            position: position.into_v2()?,
7024            timestamp_ms: timestamp_ms.into_v2()?,
7025            meta: meta.into_v2()?,
7026        })
7027    }
7028}
7029
7030#[cfg(feature = "unstable_nes")]
7031impl IntoV1 for super::NesOpenFile {
7032    type Output = crate::v1::NesOpenFile;
7033
7034    fn into_v1(self) -> Result<Self::Output> {
7035        let Self {
7036            uri,
7037            language_id,
7038            visible_range,
7039            last_focused_ms,
7040            meta,
7041        } = self;
7042        Ok(crate::v1::NesOpenFile {
7043            uri: uri.into_v1()?,
7044            language_id: language_id.into_v1()?,
7045            visible_range: into_v1_default_on_error(visible_range),
7046            last_focused_ms: into_v1_default_on_error(last_focused_ms),
7047            meta: meta.into_v1()?,
7048        })
7049    }
7050}
7051
7052#[cfg(feature = "unstable_nes")]
7053impl IntoV2 for crate::v1::NesOpenFile {
7054    type Output = super::NesOpenFile;
7055
7056    fn into_v2(self) -> Result<Self::Output> {
7057        let Self {
7058            uri,
7059            language_id,
7060            visible_range,
7061            last_focused_ms,
7062            meta,
7063        } = self;
7064        Ok(super::NesOpenFile {
7065            uri: uri.into_v2()?,
7066            language_id: language_id.into_v2()?,
7067            visible_range: into_v2_default_on_error(visible_range),
7068            last_focused_ms: into_v2_default_on_error(last_focused_ms),
7069            meta: meta.into_v2()?,
7070        })
7071    }
7072}
7073
7074#[cfg(feature = "unstable_nes")]
7075impl IntoV1 for super::NesDiagnostic {
7076    type Output = crate::v1::NesDiagnostic;
7077
7078    fn into_v1(self) -> Result<Self::Output> {
7079        let Self {
7080            uri,
7081            range,
7082            severity,
7083            message,
7084            meta,
7085        } = self;
7086        Ok(crate::v1::NesDiagnostic {
7087            uri: uri.into_v1()?,
7088            range: range.into_v1()?,
7089            severity: severity.into_v1()?,
7090            message: message.into_v1()?,
7091            meta: meta.into_v1()?,
7092        })
7093    }
7094}
7095
7096#[cfg(feature = "unstable_nes")]
7097impl IntoV2 for crate::v1::NesDiagnostic {
7098    type Output = super::NesDiagnostic;
7099
7100    fn into_v2(self) -> Result<Self::Output> {
7101        let Self {
7102            uri,
7103            range,
7104            severity,
7105            message,
7106            meta,
7107        } = self;
7108        Ok(super::NesDiagnostic {
7109            uri: uri.into_v2()?,
7110            range: range.into_v2()?,
7111            severity: severity.into_v2()?,
7112            message: message.into_v2()?,
7113            meta: meta.into_v2()?,
7114        })
7115    }
7116}
7117
7118#[cfg(feature = "unstable_nes")]
7119impl IntoV1 for super::NesDiagnosticSeverity {
7120    type Output = crate::v1::NesDiagnosticSeverity;
7121
7122    fn into_v1(self) -> Result<Self::Output> {
7123        Ok(match self {
7124            Self::Error => crate::v1::NesDiagnosticSeverity::Error,
7125            Self::Warning => crate::v1::NesDiagnosticSeverity::Warning,
7126            Self::Information => crate::v1::NesDiagnosticSeverity::Information,
7127            Self::Hint => crate::v1::NesDiagnosticSeverity::Hint,
7128            Self::Other(value) => {
7129                return Err(unknown_v2_enum_variant("NesDiagnosticSeverity", &value));
7130            }
7131        })
7132    }
7133}
7134
7135#[cfg(feature = "unstable_nes")]
7136impl IntoV2 for crate::v1::NesDiagnosticSeverity {
7137    type Output = super::NesDiagnosticSeverity;
7138
7139    fn into_v2(self) -> Result<Self::Output> {
7140        Ok(match self {
7141            Self::Error => super::NesDiagnosticSeverity::Error,
7142            Self::Warning => super::NesDiagnosticSeverity::Warning,
7143            Self::Information => super::NesDiagnosticSeverity::Information,
7144            Self::Hint => super::NesDiagnosticSeverity::Hint,
7145        })
7146    }
7147}
7148
7149#[cfg(feature = "unstable_nes")]
7150impl IntoV1 for super::SuggestNesResponse {
7151    type Output = crate::v1::SuggestNesResponse;
7152
7153    fn into_v1(self) -> Result<Self::Output> {
7154        let Self { suggestions, meta } = self;
7155        Ok(crate::v1::SuggestNesResponse {
7156            suggestions: into_v1_vec_skip_errors(suggestions),
7157            meta: meta.into_v1()?,
7158        })
7159    }
7160}
7161
7162#[cfg(feature = "unstable_nes")]
7163impl IntoV2 for crate::v1::SuggestNesResponse {
7164    type Output = super::SuggestNesResponse;
7165
7166    fn into_v2(self) -> Result<Self::Output> {
7167        let Self { suggestions, meta } = self;
7168        Ok(super::SuggestNesResponse {
7169            suggestions: into_v2_vec_skip_errors(suggestions),
7170            meta: meta.into_v2()?,
7171        })
7172    }
7173}
7174
7175#[cfg(feature = "unstable_nes")]
7176impl IntoV1 for super::NesSuggestion {
7177    type Output = crate::v1::NesSuggestion;
7178
7179    fn into_v1(self) -> Result<Self::Output> {
7180        Ok(match self {
7181            Self::Edit(value) => crate::v1::NesSuggestion::Edit(value.into_v1()?),
7182            Self::Jump(value) => crate::v1::NesSuggestion::Jump(value.into_v1()?),
7183            Self::Rename(value) => crate::v1::NesSuggestion::Rename(value.into_v1()?),
7184            Self::SearchAndReplace(value) => {
7185                crate::v1::NesSuggestion::SearchAndReplace(value.into_v1()?)
7186            }
7187            Self::Other(value) => {
7188                return Err(unknown_v2_enum_variant("NesSuggestion", &value.kind));
7189            }
7190        })
7191    }
7192}
7193
7194#[cfg(feature = "unstable_nes")]
7195impl IntoV2 for crate::v1::NesSuggestion {
7196    type Output = super::NesSuggestion;
7197
7198    fn into_v2(self) -> Result<Self::Output> {
7199        Ok(match self {
7200            Self::Edit(value) => super::NesSuggestion::Edit(value.into_v2()?),
7201            Self::Jump(value) => super::NesSuggestion::Jump(value.into_v2()?),
7202            Self::Rename(value) => super::NesSuggestion::Rename(value.into_v2()?),
7203            Self::SearchAndReplace(value) => {
7204                super::NesSuggestion::SearchAndReplace(value.into_v2()?)
7205            }
7206        })
7207    }
7208}
7209
7210#[cfg(feature = "unstable_nes")]
7211impl IntoV1 for super::NesSuggestionId {
7212    type Output = crate::v1::NesSuggestionId;
7213
7214    fn into_v1(self) -> Result<Self::Output> {
7215        Ok(crate::v1::NesSuggestionId(self.0.into_v1()?))
7216    }
7217}
7218
7219#[cfg(feature = "unstable_nes")]
7220impl IntoV2 for crate::v1::NesSuggestionId {
7221    type Output = super::NesSuggestionId;
7222
7223    fn into_v2(self) -> Result<Self::Output> {
7224        Ok(super::NesSuggestionId(self.0.into_v2()?))
7225    }
7226}
7227
7228#[cfg(feature = "unstable_nes")]
7229impl IntoV1 for super::NesEditSuggestion {
7230    type Output = crate::v1::NesEditSuggestion;
7231
7232    fn into_v1(self) -> Result<Self::Output> {
7233        let Self {
7234            suggestion_id,
7235            uri,
7236            edits,
7237            cursor_position,
7238            meta,
7239        } = self;
7240        Ok(crate::v1::NesEditSuggestion {
7241            id: suggestion_id.into_v1()?,
7242            uri: uri.into_v1()?,
7243            edits: edits.into_v1()?,
7244            cursor_position: into_v1_default_on_error(cursor_position),
7245            meta: meta.into_v1()?,
7246        })
7247    }
7248}
7249
7250#[cfg(feature = "unstable_nes")]
7251impl IntoV2 for crate::v1::NesEditSuggestion {
7252    type Output = super::NesEditSuggestion;
7253
7254    fn into_v2(self) -> Result<Self::Output> {
7255        let Self {
7256            id,
7257            uri,
7258            edits,
7259            cursor_position,
7260            meta,
7261        } = self;
7262        Ok(super::NesEditSuggestion {
7263            suggestion_id: id.into_v2()?,
7264            uri: uri.into_v2()?,
7265            edits: edits.into_v2()?,
7266            cursor_position: into_v2_default_on_error(cursor_position),
7267            meta: meta.into_v2()?,
7268        })
7269    }
7270}
7271
7272#[cfg(feature = "unstable_nes")]
7273impl IntoV1 for super::NesTextEdit {
7274    type Output = crate::v1::NesTextEdit;
7275
7276    fn into_v1(self) -> Result<Self::Output> {
7277        let Self {
7278            range,
7279            new_text,
7280            meta,
7281        } = self;
7282        Ok(crate::v1::NesTextEdit {
7283            range: range.into_v1()?,
7284            new_text: new_text.into_v1()?,
7285            meta: meta.into_v1()?,
7286        })
7287    }
7288}
7289
7290#[cfg(feature = "unstable_nes")]
7291impl IntoV2 for crate::v1::NesTextEdit {
7292    type Output = super::NesTextEdit;
7293
7294    fn into_v2(self) -> Result<Self::Output> {
7295        let Self {
7296            range,
7297            new_text,
7298            meta,
7299        } = self;
7300        Ok(super::NesTextEdit {
7301            range: range.into_v2()?,
7302            new_text: new_text.into_v2()?,
7303            meta: meta.into_v2()?,
7304        })
7305    }
7306}
7307
7308#[cfg(feature = "unstable_nes")]
7309impl IntoV1 for super::NesJumpSuggestion {
7310    type Output = crate::v1::NesJumpSuggestion;
7311
7312    fn into_v1(self) -> Result<Self::Output> {
7313        let Self {
7314            suggestion_id,
7315            uri,
7316            position,
7317            meta,
7318        } = self;
7319        Ok(crate::v1::NesJumpSuggestion {
7320            id: suggestion_id.into_v1()?,
7321            uri: uri.into_v1()?,
7322            position: position.into_v1()?,
7323            meta: meta.into_v1()?,
7324        })
7325    }
7326}
7327
7328#[cfg(feature = "unstable_nes")]
7329impl IntoV2 for crate::v1::NesJumpSuggestion {
7330    type Output = super::NesJumpSuggestion;
7331
7332    fn into_v2(self) -> Result<Self::Output> {
7333        let Self {
7334            id,
7335            uri,
7336            position,
7337            meta,
7338        } = self;
7339        Ok(super::NesJumpSuggestion {
7340            suggestion_id: id.into_v2()?,
7341            uri: uri.into_v2()?,
7342            position: position.into_v2()?,
7343            meta: meta.into_v2()?,
7344        })
7345    }
7346}
7347
7348#[cfg(feature = "unstable_nes")]
7349impl IntoV1 for super::NesRenameSuggestion {
7350    type Output = crate::v1::NesRenameSuggestion;
7351
7352    fn into_v1(self) -> Result<Self::Output> {
7353        let Self {
7354            suggestion_id,
7355            uri,
7356            position,
7357            new_name,
7358            meta,
7359        } = self;
7360        Ok(crate::v1::NesRenameSuggestion {
7361            id: suggestion_id.into_v1()?,
7362            uri: uri.into_v1()?,
7363            position: position.into_v1()?,
7364            new_name: new_name.into_v1()?,
7365            meta: meta.into_v1()?,
7366        })
7367    }
7368}
7369
7370#[cfg(feature = "unstable_nes")]
7371impl IntoV2 for crate::v1::NesRenameSuggestion {
7372    type Output = super::NesRenameSuggestion;
7373
7374    fn into_v2(self) -> Result<Self::Output> {
7375        let Self {
7376            id,
7377            uri,
7378            position,
7379            new_name,
7380            meta,
7381        } = self;
7382        Ok(super::NesRenameSuggestion {
7383            suggestion_id: id.into_v2()?,
7384            uri: uri.into_v2()?,
7385            position: position.into_v2()?,
7386            new_name: new_name.into_v2()?,
7387            meta: meta.into_v2()?,
7388        })
7389    }
7390}
7391
7392#[cfg(feature = "unstable_nes")]
7393impl IntoV1 for super::NesSearchAndReplaceSuggestion {
7394    type Output = crate::v1::NesSearchAndReplaceSuggestion;
7395
7396    fn into_v1(self) -> Result<Self::Output> {
7397        let Self {
7398            suggestion_id,
7399            uri,
7400            search,
7401            replace,
7402            is_regex,
7403            meta,
7404        } = self;
7405        Ok(crate::v1::NesSearchAndReplaceSuggestion {
7406            id: suggestion_id.into_v1()?,
7407            uri: uri.into_v1()?,
7408            search: search.into_v1()?,
7409            replace: replace.into_v1()?,
7410            is_regex: is_regex.into_v1()?,
7411            meta: meta.into_v1()?,
7412        })
7413    }
7414}
7415
7416#[cfg(feature = "unstable_nes")]
7417impl IntoV2 for crate::v1::NesSearchAndReplaceSuggestion {
7418    type Output = super::NesSearchAndReplaceSuggestion;
7419
7420    fn into_v2(self) -> Result<Self::Output> {
7421        let Self {
7422            id,
7423            uri,
7424            search,
7425            replace,
7426            is_regex,
7427            meta,
7428        } = self;
7429        Ok(super::NesSearchAndReplaceSuggestion {
7430            suggestion_id: id.into_v2()?,
7431            uri: uri.into_v2()?,
7432            search: search.into_v2()?,
7433            replace: replace.into_v2()?,
7434            is_regex: is_regex.into_v2()?,
7435            meta: meta.into_v2()?,
7436        })
7437    }
7438}
7439
7440#[cfg(feature = "unstable_nes")]
7441impl IntoV1 for super::AcceptNesNotification {
7442    type Output = crate::v1::AcceptNesNotification;
7443
7444    fn into_v1(self) -> Result<Self::Output> {
7445        let Self {
7446            session_id,
7447            suggestion_id,
7448            meta,
7449        } = self;
7450        Ok(crate::v1::AcceptNesNotification {
7451            session_id: session_id.into_v1()?,
7452            id: suggestion_id.into_v1()?,
7453            meta: meta.into_v1()?,
7454        })
7455    }
7456}
7457
7458#[cfg(feature = "unstable_nes")]
7459impl IntoV2 for crate::v1::AcceptNesNotification {
7460    type Output = super::AcceptNesNotification;
7461
7462    fn into_v2(self) -> Result<Self::Output> {
7463        let Self {
7464            session_id,
7465            id,
7466            meta,
7467        } = self;
7468        Ok(super::AcceptNesNotification {
7469            session_id: session_id.into_v2()?,
7470            suggestion_id: id.into_v2()?,
7471            meta: meta.into_v2()?,
7472        })
7473    }
7474}
7475
7476#[cfg(feature = "unstable_nes")]
7477impl IntoV1 for super::RejectNesNotification {
7478    type Output = crate::v1::RejectNesNotification;
7479
7480    fn into_v1(self) -> Result<Self::Output> {
7481        let Self {
7482            session_id,
7483            suggestion_id,
7484            reason,
7485            meta,
7486        } = self;
7487        Ok(crate::v1::RejectNesNotification {
7488            session_id: session_id.into_v1()?,
7489            id: suggestion_id.into_v1()?,
7490            reason: into_v1_default_on_error(reason),
7491            meta: meta.into_v1()?,
7492        })
7493    }
7494}
7495
7496#[cfg(feature = "unstable_nes")]
7497impl IntoV2 for crate::v1::RejectNesNotification {
7498    type Output = super::RejectNesNotification;
7499
7500    fn into_v2(self) -> Result<Self::Output> {
7501        let Self {
7502            session_id,
7503            id,
7504            reason,
7505            meta,
7506        } = self;
7507        Ok(super::RejectNesNotification {
7508            session_id: session_id.into_v2()?,
7509            suggestion_id: id.into_v2()?,
7510            reason: into_v2_default_on_error(reason),
7511            meta: meta.into_v2()?,
7512        })
7513    }
7514}
7515
7516#[cfg(feature = "unstable_nes")]
7517impl IntoV1 for super::NesRejectReason {
7518    type Output = crate::v1::NesRejectReason;
7519
7520    fn into_v1(self) -> Result<Self::Output> {
7521        Ok(match self {
7522            Self::Rejected => crate::v1::NesRejectReason::Rejected,
7523            Self::Ignored => crate::v1::NesRejectReason::Ignored,
7524            Self::Replaced => crate::v1::NesRejectReason::Replaced,
7525            Self::Cancelled => crate::v1::NesRejectReason::Cancelled,
7526            Self::Other(value) => return Err(unknown_v2_enum_variant("NesRejectReason", &value)),
7527        })
7528    }
7529}
7530
7531#[cfg(feature = "unstable_nes")]
7532impl IntoV2 for crate::v1::NesRejectReason {
7533    type Output = super::NesRejectReason;
7534
7535    fn into_v2(self) -> Result<Self::Output> {
7536        Ok(match self {
7537            Self::Rejected => super::NesRejectReason::Rejected,
7538            Self::Ignored => super::NesRejectReason::Ignored,
7539            Self::Replaced => super::NesRejectReason::Replaced,
7540            Self::Cancelled => super::NesRejectReason::Cancelled,
7541        })
7542    }
7543}
7544
7545#[cfg(feature = "unstable_elicitation")]
7546impl IntoV1 for super::ElicitationId {
7547    type Output = crate::v1::ElicitationId;
7548
7549    fn into_v1(self) -> Result<Self::Output> {
7550        Ok(crate::v1::ElicitationId(self.0.into_v1()?))
7551    }
7552}
7553
7554#[cfg(feature = "unstable_elicitation")]
7555impl IntoV2 for crate::v1::ElicitationId {
7556    type Output = super::ElicitationId;
7557
7558    fn into_v2(self) -> Result<Self::Output> {
7559        Ok(super::ElicitationId(self.0.into_v2()?))
7560    }
7561}
7562
7563#[cfg(feature = "unstable_elicitation")]
7564impl IntoV1 for super::StringFormat {
7565    type Output = crate::v1::StringFormat;
7566
7567    fn into_v1(self) -> Result<Self::Output> {
7568        Ok(match self {
7569            Self::Email => crate::v1::StringFormat::Email,
7570            Self::Uri => crate::v1::StringFormat::Uri,
7571            Self::Date => crate::v1::StringFormat::Date,
7572            Self::DateTime => crate::v1::StringFormat::DateTime,
7573            Self::Other(value) => return Err(unknown_v2_enum_variant("StringFormat", &value)),
7574        })
7575    }
7576}
7577
7578#[cfg(feature = "unstable_elicitation")]
7579impl IntoV2 for crate::v1::StringFormat {
7580    type Output = super::StringFormat;
7581
7582    fn into_v2(self) -> Result<Self::Output> {
7583        Ok(match self {
7584            Self::Email => super::StringFormat::Email,
7585            Self::Uri => super::StringFormat::Uri,
7586            Self::Date => super::StringFormat::Date,
7587            Self::DateTime => super::StringFormat::DateTime,
7588        })
7589    }
7590}
7591
7592#[cfg(feature = "unstable_elicitation")]
7593impl IntoV1 for super::ElicitationSchemaType {
7594    type Output = crate::v1::ElicitationSchemaType;
7595
7596    fn into_v1(self) -> Result<Self::Output> {
7597        Ok(match self {
7598            Self::Object => crate::v1::ElicitationSchemaType::Object,
7599        })
7600    }
7601}
7602
7603#[cfg(feature = "unstable_elicitation")]
7604impl IntoV2 for crate::v1::ElicitationSchemaType {
7605    type Output = super::ElicitationSchemaType;
7606
7607    fn into_v2(self) -> Result<Self::Output> {
7608        Ok(match self {
7609            Self::Object => super::ElicitationSchemaType::Object,
7610        })
7611    }
7612}
7613
7614#[cfg(feature = "unstable_elicitation")]
7615impl IntoV1 for super::EnumOption {
7616    type Output = crate::v1::EnumOption;
7617
7618    fn into_v1(self) -> Result<Self::Output> {
7619        let Self {
7620            value,
7621            title,
7622            description,
7623            meta,
7624        } = self;
7625        Ok(crate::v1::EnumOption {
7626            value: value.into_v1()?,
7627            title: title.into_v1()?,
7628            description: description.into_v1()?,
7629            meta: meta.into_v1()?,
7630        })
7631    }
7632}
7633
7634#[cfg(feature = "unstable_elicitation")]
7635impl IntoV2 for crate::v1::EnumOption {
7636    type Output = super::EnumOption;
7637
7638    fn into_v2(self) -> Result<Self::Output> {
7639        let Self {
7640            value,
7641            title,
7642            description,
7643            meta,
7644        } = self;
7645        Ok(super::EnumOption {
7646            value: value.into_v2()?,
7647            title: title.into_v2()?,
7648            description: description.into_v2()?,
7649            meta: meta.into_v2()?,
7650        })
7651    }
7652}
7653
7654#[cfg(feature = "unstable_elicitation")]
7655impl IntoV1 for super::StringPropertySchema {
7656    type Output = crate::v1::StringPropertySchema;
7657
7658    fn into_v1(self) -> Result<Self::Output> {
7659        let Self {
7660            title,
7661            description,
7662            min_length,
7663            max_length,
7664            pattern,
7665            format,
7666            default,
7667            enum_values,
7668            one_of,
7669            meta,
7670        } = self;
7671        Ok(crate::v1::StringPropertySchema {
7672            title: title.into_v1()?,
7673            description: description.into_v1()?,
7674            min_length: min_length.into_v1()?,
7675            max_length: max_length.into_v1()?,
7676            pattern: pattern.into_v1()?,
7677            format: format.into_v1()?,
7678            default: default.into_v1()?,
7679            enum_values: enum_values.into_v1()?,
7680            one_of: one_of.into_v1()?,
7681            meta: meta.into_v1()?,
7682        })
7683    }
7684}
7685
7686#[cfg(feature = "unstable_elicitation")]
7687impl IntoV2 for crate::v1::StringPropertySchema {
7688    type Output = super::StringPropertySchema;
7689
7690    fn into_v2(self) -> Result<Self::Output> {
7691        let Self {
7692            title,
7693            description,
7694            min_length,
7695            max_length,
7696            pattern,
7697            format,
7698            default,
7699            enum_values,
7700            one_of,
7701            meta,
7702        } = self;
7703        Ok(super::StringPropertySchema {
7704            title: title.into_v2()?,
7705            description: description.into_v2()?,
7706            min_length: min_length.into_v2()?,
7707            max_length: max_length.into_v2()?,
7708            pattern: pattern.into_v2()?,
7709            format: format.into_v2()?,
7710            default: default.into_v2()?,
7711            enum_values: enum_values.into_v2()?,
7712            one_of: one_of.into_v2()?,
7713            meta: meta.into_v2()?,
7714        })
7715    }
7716}
7717
7718#[cfg(feature = "unstable_elicitation")]
7719impl IntoV1 for super::NumberPropertySchema {
7720    type Output = crate::v1::NumberPropertySchema;
7721
7722    fn into_v1(self) -> Result<Self::Output> {
7723        let Self {
7724            title,
7725            description,
7726            minimum,
7727            maximum,
7728            default,
7729            meta,
7730        } = self;
7731        Ok(crate::v1::NumberPropertySchema {
7732            title: title.into_v1()?,
7733            description: description.into_v1()?,
7734            minimum: minimum.into_v1()?,
7735            maximum: maximum.into_v1()?,
7736            default: default.into_v1()?,
7737            meta: meta.into_v1()?,
7738        })
7739    }
7740}
7741
7742#[cfg(feature = "unstable_elicitation")]
7743impl IntoV2 for crate::v1::NumberPropertySchema {
7744    type Output = super::NumberPropertySchema;
7745
7746    fn into_v2(self) -> Result<Self::Output> {
7747        let Self {
7748            title,
7749            description,
7750            minimum,
7751            maximum,
7752            default,
7753            meta,
7754        } = self;
7755        Ok(super::NumberPropertySchema {
7756            title: title.into_v2()?,
7757            description: description.into_v2()?,
7758            minimum: minimum.into_v2()?,
7759            maximum: maximum.into_v2()?,
7760            default: default.into_v2()?,
7761            meta: meta.into_v2()?,
7762        })
7763    }
7764}
7765
7766#[cfg(feature = "unstable_elicitation")]
7767impl IntoV1 for super::IntegerPropertySchema {
7768    type Output = crate::v1::IntegerPropertySchema;
7769
7770    fn into_v1(self) -> Result<Self::Output> {
7771        let Self {
7772            title,
7773            description,
7774            minimum,
7775            maximum,
7776            default,
7777            meta,
7778        } = self;
7779        Ok(crate::v1::IntegerPropertySchema {
7780            title: title.into_v1()?,
7781            description: description.into_v1()?,
7782            minimum: minimum.into_v1()?,
7783            maximum: maximum.into_v1()?,
7784            default: default.into_v1()?,
7785            meta: meta.into_v1()?,
7786        })
7787    }
7788}
7789
7790#[cfg(feature = "unstable_elicitation")]
7791impl IntoV2 for crate::v1::IntegerPropertySchema {
7792    type Output = super::IntegerPropertySchema;
7793
7794    fn into_v2(self) -> Result<Self::Output> {
7795        let Self {
7796            title,
7797            description,
7798            minimum,
7799            maximum,
7800            default,
7801            meta,
7802        } = self;
7803        Ok(super::IntegerPropertySchema {
7804            title: title.into_v2()?,
7805            description: description.into_v2()?,
7806            minimum: minimum.into_v2()?,
7807            maximum: maximum.into_v2()?,
7808            default: default.into_v2()?,
7809            meta: meta.into_v2()?,
7810        })
7811    }
7812}
7813
7814#[cfg(feature = "unstable_elicitation")]
7815impl IntoV1 for super::BooleanPropertySchema {
7816    type Output = crate::v1::BooleanPropertySchema;
7817
7818    fn into_v1(self) -> Result<Self::Output> {
7819        let Self {
7820            title,
7821            description,
7822            default,
7823            meta,
7824        } = self;
7825        Ok(crate::v1::BooleanPropertySchema {
7826            title: title.into_v1()?,
7827            description: description.into_v1()?,
7828            default: default.into_v1()?,
7829            meta: meta.into_v1()?,
7830        })
7831    }
7832}
7833
7834#[cfg(feature = "unstable_elicitation")]
7835impl IntoV2 for crate::v1::BooleanPropertySchema {
7836    type Output = super::BooleanPropertySchema;
7837
7838    fn into_v2(self) -> Result<Self::Output> {
7839        let Self {
7840            title,
7841            description,
7842            default,
7843            meta,
7844        } = self;
7845        Ok(super::BooleanPropertySchema {
7846            title: title.into_v2()?,
7847            description: description.into_v2()?,
7848            default: default.into_v2()?,
7849            meta: meta.into_v2()?,
7850        })
7851    }
7852}
7853
7854#[cfg(feature = "unstable_elicitation")]
7855impl IntoV1 for super::StringMultiSelectItems {
7856    type Output = crate::v1::StringMultiSelectItems;
7857
7858    fn into_v1(self) -> Result<Self::Output> {
7859        let Self { values, meta } = self;
7860        Ok(crate::v1::StringMultiSelectItems {
7861            values: values.into_v1()?,
7862            meta: meta.into_v1()?,
7863        })
7864    }
7865}
7866
7867#[cfg(feature = "unstable_elicitation")]
7868impl IntoV2 for crate::v1::StringMultiSelectItems {
7869    type Output = super::StringMultiSelectItems;
7870
7871    fn into_v2(self) -> Result<Self::Output> {
7872        let Self { values, meta } = self;
7873        Ok(super::StringMultiSelectItems {
7874            values: values.into_v2()?,
7875            meta: meta.into_v2()?,
7876        })
7877    }
7878}
7879
7880#[cfg(feature = "unstable_elicitation")]
7881impl IntoV1 for super::OtherMultiSelectItems {
7882    type Output = crate::v1::OtherMultiSelectItems;
7883
7884    fn into_v1(self) -> Result<Self::Output> {
7885        let Self { type_, fields } = self;
7886        Ok(crate::v1::OtherMultiSelectItems {
7887            type_: type_.into_v1()?,
7888            fields: fields.into_v1()?,
7889        })
7890    }
7891}
7892
7893#[cfg(feature = "unstable_elicitation")]
7894impl IntoV2 for crate::v1::OtherMultiSelectItems {
7895    type Output = super::OtherMultiSelectItems;
7896
7897    fn into_v2(self) -> Result<Self::Output> {
7898        let Self { type_, fields } = self;
7899        Ok(super::OtherMultiSelectItems {
7900            type_: type_.into_v2()?,
7901            fields: fields.into_v2()?,
7902        })
7903    }
7904}
7905
7906#[cfg(feature = "unstable_elicitation")]
7907impl IntoV1 for super::TitledMultiSelectItems {
7908    type Output = crate::v1::TitledMultiSelectItems;
7909
7910    fn into_v1(self) -> Result<Self::Output> {
7911        let Self { options, meta } = self;
7912        Ok(crate::v1::TitledMultiSelectItems {
7913            options: options.into_v1()?,
7914            meta: meta.into_v1()?,
7915        })
7916    }
7917}
7918
7919#[cfg(feature = "unstable_elicitation")]
7920impl IntoV2 for crate::v1::TitledMultiSelectItems {
7921    type Output = super::TitledMultiSelectItems;
7922
7923    fn into_v2(self) -> Result<Self::Output> {
7924        let Self { options, meta } = self;
7925        Ok(super::TitledMultiSelectItems {
7926            options: options.into_v2()?,
7927            meta: meta.into_v2()?,
7928        })
7929    }
7930}
7931
7932#[cfg(feature = "unstable_elicitation")]
7933impl IntoV1 for super::MultiSelectItems {
7934    type Output = crate::v1::MultiSelectItems;
7935
7936    fn into_v1(self) -> Result<Self::Output> {
7937        Ok(match self {
7938            Self::String(value) => crate::v1::MultiSelectItems::String(value.into_v1()?),
7939            Self::Other(value) => crate::v1::MultiSelectItems::Other(value.into_v1()?),
7940            Self::Titled(value) => crate::v1::MultiSelectItems::Titled(value.into_v1()?),
7941        })
7942    }
7943}
7944
7945#[cfg(feature = "unstable_elicitation")]
7946impl IntoV2 for crate::v1::MultiSelectItems {
7947    type Output = super::MultiSelectItems;
7948
7949    fn into_v2(self) -> Result<Self::Output> {
7950        Ok(match self {
7951            Self::String(value) => super::MultiSelectItems::String(value.into_v2()?),
7952            Self::Other(value) => super::MultiSelectItems::Other(value.into_v2()?),
7953            Self::Titled(value) => super::MultiSelectItems::Titled(value.into_v2()?),
7954        })
7955    }
7956}
7957
7958#[cfg(feature = "unstable_elicitation")]
7959impl IntoV1 for super::MultiSelectPropertySchema {
7960    type Output = crate::v1::MultiSelectPropertySchema;
7961
7962    fn into_v1(self) -> Result<Self::Output> {
7963        let Self {
7964            title,
7965            description,
7966            min_items,
7967            max_items,
7968            items,
7969            default,
7970            meta,
7971        } = self;
7972        Ok(crate::v1::MultiSelectPropertySchema {
7973            title: title.into_v1()?,
7974            description: description.into_v1()?,
7975            min_items: min_items.into_v1()?,
7976            max_items: max_items.into_v1()?,
7977            items: items.into_v1()?,
7978            default: default.into_v1()?,
7979            meta: meta.into_v1()?,
7980        })
7981    }
7982}
7983
7984#[cfg(feature = "unstable_elicitation")]
7985impl IntoV2 for crate::v1::MultiSelectPropertySchema {
7986    type Output = super::MultiSelectPropertySchema;
7987
7988    fn into_v2(self) -> Result<Self::Output> {
7989        let Self {
7990            title,
7991            description,
7992            min_items,
7993            max_items,
7994            items,
7995            default,
7996            meta,
7997        } = self;
7998        Ok(super::MultiSelectPropertySchema {
7999            title: title.into_v2()?,
8000            description: description.into_v2()?,
8001            min_items: min_items.into_v2()?,
8002            max_items: max_items.into_v2()?,
8003            items: items.into_v2()?,
8004            default: default.into_v2()?,
8005            meta: meta.into_v2()?,
8006        })
8007    }
8008}
8009
8010#[cfg(feature = "unstable_elicitation")]
8011impl IntoV1 for super::ElicitationPropertySchema {
8012    type Output = crate::v1::ElicitationPropertySchema;
8013
8014    fn into_v1(self) -> Result<Self::Output> {
8015        Ok(match self {
8016            Self::String(value) => crate::v1::ElicitationPropertySchema::String(value.into_v1()?),
8017            Self::Number(value) => crate::v1::ElicitationPropertySchema::Number(value.into_v1()?),
8018            Self::Integer(value) => crate::v1::ElicitationPropertySchema::Integer(value.into_v1()?),
8019            Self::Boolean(value) => crate::v1::ElicitationPropertySchema::Boolean(value.into_v1()?),
8020            Self::Array(value) => crate::v1::ElicitationPropertySchema::Array(value.into_v1()?),
8021            Self::Other(value) => crate::v1::ElicitationPropertySchema::Other(value.into_v1()?),
8022        })
8023    }
8024}
8025
8026#[cfg(feature = "unstable_elicitation")]
8027impl IntoV2 for crate::v1::ElicitationPropertySchema {
8028    type Output = super::ElicitationPropertySchema;
8029
8030    fn into_v2(self) -> Result<Self::Output> {
8031        Ok(match self {
8032            Self::String(value) => super::ElicitationPropertySchema::String(value.into_v2()?),
8033            Self::Number(value) => super::ElicitationPropertySchema::Number(value.into_v2()?),
8034            Self::Integer(value) => super::ElicitationPropertySchema::Integer(value.into_v2()?),
8035            Self::Boolean(value) => super::ElicitationPropertySchema::Boolean(value.into_v2()?),
8036            Self::Array(value) => super::ElicitationPropertySchema::Array(value.into_v2()?),
8037            Self::Other(value) => super::ElicitationPropertySchema::Other(value.into_v2()?),
8038        })
8039    }
8040}
8041
8042#[cfg(feature = "unstable_elicitation")]
8043impl IntoV1 for super::OtherElicitationPropertySchema {
8044    type Output = crate::v1::OtherElicitationPropertySchema;
8045
8046    fn into_v1(self) -> Result<Self::Output> {
8047        let Self { type_, fields } = self;
8048        Ok(crate::v1::OtherElicitationPropertySchema {
8049            type_: type_.into_v1()?,
8050            fields: fields.into_v1()?,
8051        })
8052    }
8053}
8054
8055#[cfg(feature = "unstable_elicitation")]
8056impl IntoV2 for crate::v1::OtherElicitationPropertySchema {
8057    type Output = super::OtherElicitationPropertySchema;
8058
8059    fn into_v2(self) -> Result<Self::Output> {
8060        let Self { type_, fields } = self;
8061        Ok(super::OtherElicitationPropertySchema {
8062            type_: type_.into_v2()?,
8063            fields: fields.into_v2()?,
8064        })
8065    }
8066}
8067
8068#[cfg(feature = "unstable_elicitation")]
8069impl IntoV1 for super::ElicitationSchema {
8070    type Output = crate::v1::ElicitationSchema;
8071
8072    fn into_v1(self) -> Result<Self::Output> {
8073        let Self {
8074            type_,
8075            title,
8076            properties,
8077            required,
8078            description,
8079            meta,
8080        } = self;
8081        Ok(crate::v1::ElicitationSchema {
8082            type_: type_.into_v1()?,
8083            title: title.into_v1()?,
8084            properties: properties.into_v1()?,
8085            required: required.into_v1()?,
8086            description: description.into_v1()?,
8087            meta: meta.into_v1()?,
8088        })
8089    }
8090}
8091
8092#[cfg(feature = "unstable_elicitation")]
8093impl IntoV2 for crate::v1::ElicitationSchema {
8094    type Output = super::ElicitationSchema;
8095
8096    fn into_v2(self) -> Result<Self::Output> {
8097        let Self {
8098            type_,
8099            title,
8100            properties,
8101            required,
8102            description,
8103            meta,
8104        } = self;
8105        Ok(super::ElicitationSchema {
8106            type_: type_.into_v2()?,
8107            title: title.into_v2()?,
8108            properties: properties.into_v2()?,
8109            required: required.into_v2()?,
8110            description: description.into_v2()?,
8111            meta: meta.into_v2()?,
8112        })
8113    }
8114}
8115
8116#[cfg(feature = "unstable_elicitation")]
8117impl IntoV1 for super::ElicitationCapabilities {
8118    type Output = crate::v1::ElicitationCapabilities;
8119
8120    fn into_v1(self) -> Result<Self::Output> {
8121        let Self { form, url, meta } = self;
8122        Ok(crate::v1::ElicitationCapabilities {
8123            form: into_v1_default_on_error(form),
8124            url: into_v1_default_on_error(url),
8125            meta: meta.into_v1()?,
8126        })
8127    }
8128}
8129
8130#[cfg(feature = "unstable_elicitation")]
8131impl IntoV2 for crate::v1::ElicitationCapabilities {
8132    type Output = super::ElicitationCapabilities;
8133
8134    fn into_v2(self) -> Result<Self::Output> {
8135        let Self { form, url, meta } = self;
8136        Ok(super::ElicitationCapabilities {
8137            form: into_v2_default_on_error(form),
8138            url: into_v2_default_on_error(url),
8139            meta: meta.into_v2()?,
8140        })
8141    }
8142}
8143
8144#[cfg(feature = "unstable_elicitation")]
8145impl IntoV1 for super::ElicitationFormCapabilities {
8146    type Output = crate::v1::ElicitationFormCapabilities;
8147
8148    fn into_v1(self) -> Result<Self::Output> {
8149        let Self { meta } = self;
8150        Ok(crate::v1::ElicitationFormCapabilities {
8151            meta: meta.into_v1()?,
8152        })
8153    }
8154}
8155
8156#[cfg(feature = "unstable_elicitation")]
8157impl IntoV2 for crate::v1::ElicitationFormCapabilities {
8158    type Output = super::ElicitationFormCapabilities;
8159
8160    fn into_v2(self) -> Result<Self::Output> {
8161        let Self { meta } = self;
8162        Ok(super::ElicitationFormCapabilities {
8163            meta: meta.into_v2()?,
8164        })
8165    }
8166}
8167
8168#[cfg(feature = "unstable_elicitation")]
8169impl IntoV1 for super::ElicitationUrlCapabilities {
8170    type Output = crate::v1::ElicitationUrlCapabilities;
8171
8172    fn into_v1(self) -> Result<Self::Output> {
8173        let Self { meta } = self;
8174        Ok(crate::v1::ElicitationUrlCapabilities {
8175            meta: meta.into_v1()?,
8176        })
8177    }
8178}
8179
8180#[cfg(feature = "unstable_elicitation")]
8181impl IntoV2 for crate::v1::ElicitationUrlCapabilities {
8182    type Output = super::ElicitationUrlCapabilities;
8183
8184    fn into_v2(self) -> Result<Self::Output> {
8185        let Self { meta } = self;
8186        Ok(super::ElicitationUrlCapabilities {
8187            meta: meta.into_v2()?,
8188        })
8189    }
8190}
8191
8192#[cfg(feature = "unstable_elicitation")]
8193impl IntoV1 for super::ElicitationScope {
8194    type Output = crate::v1::ElicitationScope;
8195
8196    fn into_v1(self) -> Result<Self::Output> {
8197        Ok(match self {
8198            Self::Session(value) => crate::v1::ElicitationScope::Session(value.into_v1()?),
8199            Self::Request(value) => crate::v1::ElicitationScope::Request(value.into_v1()?),
8200        })
8201    }
8202}
8203
8204#[cfg(feature = "unstable_elicitation")]
8205impl IntoV2 for crate::v1::ElicitationScope {
8206    type Output = super::ElicitationScope;
8207
8208    fn into_v2(self) -> Result<Self::Output> {
8209        Ok(match self {
8210            Self::Session(value) => super::ElicitationScope::Session(value.into_v2()?),
8211            Self::Request(value) => super::ElicitationScope::Request(value.into_v2()?),
8212        })
8213    }
8214}
8215
8216#[cfg(feature = "unstable_elicitation")]
8217impl IntoV1 for super::ElicitationSessionScope {
8218    type Output = crate::v1::ElicitationSessionScope;
8219
8220    fn into_v1(self) -> Result<Self::Output> {
8221        let Self {
8222            session_id,
8223            tool_call_id,
8224        } = self;
8225        Ok(crate::v1::ElicitationSessionScope {
8226            session_id: session_id.into_v1()?,
8227            tool_call_id: tool_call_id.into_v1()?,
8228        })
8229    }
8230}
8231
8232#[cfg(feature = "unstable_elicitation")]
8233impl IntoV2 for crate::v1::ElicitationSessionScope {
8234    type Output = super::ElicitationSessionScope;
8235
8236    fn into_v2(self) -> Result<Self::Output> {
8237        let Self {
8238            session_id,
8239            tool_call_id,
8240        } = self;
8241        Ok(super::ElicitationSessionScope {
8242            session_id: session_id.into_v2()?,
8243            tool_call_id: tool_call_id.into_v2()?,
8244        })
8245    }
8246}
8247
8248#[cfg(feature = "unstable_elicitation")]
8249impl IntoV1 for super::ElicitationRequestScope {
8250    type Output = crate::v1::ElicitationRequestScope;
8251
8252    fn into_v1(self) -> Result<Self::Output> {
8253        let Self { request_id } = self;
8254        Ok(crate::v1::ElicitationRequestScope {
8255            request_id: request_id.into_v1()?,
8256        })
8257    }
8258}
8259
8260#[cfg(feature = "unstable_elicitation")]
8261impl IntoV2 for crate::v1::ElicitationRequestScope {
8262    type Output = super::ElicitationRequestScope;
8263
8264    fn into_v2(self) -> Result<Self::Output> {
8265        let Self { request_id } = self;
8266        Ok(super::ElicitationRequestScope {
8267            request_id: request_id.into_v2()?,
8268        })
8269    }
8270}
8271
8272#[cfg(feature = "unstable_elicitation")]
8273impl IntoV1 for super::CreateElicitationRequest {
8274    type Output = crate::v1::CreateElicitationRequest;
8275
8276    fn into_v1(self) -> Result<Self::Output> {
8277        let Self {
8278            mode,
8279            message,
8280            meta,
8281        } = self;
8282        Ok(crate::v1::CreateElicitationRequest {
8283            mode: mode.into_v1()?,
8284            message: message.into_v1()?,
8285            meta: meta.into_v1()?,
8286        })
8287    }
8288}
8289
8290#[cfg(feature = "unstable_elicitation")]
8291impl IntoV2 for crate::v1::CreateElicitationRequest {
8292    type Output = super::CreateElicitationRequest;
8293
8294    fn into_v2(self) -> Result<Self::Output> {
8295        let Self {
8296            mode,
8297            message,
8298            meta,
8299        } = self;
8300        Ok(super::CreateElicitationRequest {
8301            mode: mode.into_v2()?,
8302            message: message.into_v2()?,
8303            meta: meta.into_v2()?,
8304        })
8305    }
8306}
8307
8308#[cfg(feature = "unstable_elicitation")]
8309impl IntoV1 for super::ElicitationMode {
8310    type Output = crate::v1::ElicitationMode;
8311
8312    fn into_v1(self) -> Result<Self::Output> {
8313        Ok(match self {
8314            Self::Form(value) => crate::v1::ElicitationMode::Form(value.into_v1()?),
8315            Self::Url(value) => crate::v1::ElicitationMode::Url(value.into_v1()?),
8316            Self::Other(value) => crate::v1::ElicitationMode::Other(value.into_v1()?),
8317        })
8318    }
8319}
8320
8321#[cfg(feature = "unstable_elicitation")]
8322impl IntoV2 for crate::v1::ElicitationMode {
8323    type Output = super::ElicitationMode;
8324
8325    fn into_v2(self) -> Result<Self::Output> {
8326        Ok(match self {
8327            Self::Form(value) => super::ElicitationMode::Form(value.into_v2()?),
8328            Self::Url(value) => super::ElicitationMode::Url(value.into_v2()?),
8329            Self::Other(value) => super::ElicitationMode::Other(value.into_v2()?),
8330        })
8331    }
8332}
8333
8334#[cfg(feature = "unstable_elicitation")]
8335impl IntoV1 for super::OtherElicitationMode {
8336    type Output = crate::v1::OtherElicitationMode;
8337
8338    fn into_v1(self) -> Result<Self::Output> {
8339        let Self {
8340            mode,
8341            scope,
8342            fields,
8343        } = self;
8344        Ok(crate::v1::OtherElicitationMode {
8345            mode: mode.into_v1()?,
8346            scope: scope.into_v1()?,
8347            fields: fields.into_v1()?,
8348        })
8349    }
8350}
8351
8352#[cfg(feature = "unstable_elicitation")]
8353impl IntoV2 for crate::v1::OtherElicitationMode {
8354    type Output = super::OtherElicitationMode;
8355
8356    fn into_v2(self) -> Result<Self::Output> {
8357        let Self {
8358            mode,
8359            scope,
8360            fields,
8361        } = self;
8362        Ok(super::OtherElicitationMode {
8363            mode: mode.into_v2()?,
8364            scope: scope.into_v2()?,
8365            fields: fields.into_v2()?,
8366        })
8367    }
8368}
8369
8370#[cfg(feature = "unstable_elicitation")]
8371impl IntoV1 for super::ElicitationFormMode {
8372    type Output = crate::v1::ElicitationFormMode;
8373
8374    fn into_v1(self) -> Result<Self::Output> {
8375        let Self {
8376            scope,
8377            requested_schema,
8378        } = self;
8379        Ok(crate::v1::ElicitationFormMode {
8380            scope: scope.into_v1()?,
8381            requested_schema: requested_schema.into_v1()?,
8382        })
8383    }
8384}
8385
8386#[cfg(feature = "unstable_elicitation")]
8387impl IntoV2 for crate::v1::ElicitationFormMode {
8388    type Output = super::ElicitationFormMode;
8389
8390    fn into_v2(self) -> Result<Self::Output> {
8391        let Self {
8392            scope,
8393            requested_schema,
8394        } = self;
8395        Ok(super::ElicitationFormMode {
8396            scope: scope.into_v2()?,
8397            requested_schema: requested_schema.into_v2()?,
8398        })
8399    }
8400}
8401
8402#[cfg(feature = "unstable_elicitation")]
8403impl IntoV1 for super::ElicitationUrlMode {
8404    type Output = crate::v1::ElicitationUrlMode;
8405
8406    fn into_v1(self) -> Result<Self::Output> {
8407        let Self {
8408            scope,
8409            elicitation_id,
8410            url,
8411        } = self;
8412        Ok(crate::v1::ElicitationUrlMode {
8413            scope: scope.into_v1()?,
8414            elicitation_id: elicitation_id.into_v1()?,
8415            url: url.into_v1()?,
8416        })
8417    }
8418}
8419
8420#[cfg(feature = "unstable_elicitation")]
8421impl IntoV2 for crate::v1::ElicitationUrlMode {
8422    type Output = super::ElicitationUrlMode;
8423
8424    fn into_v2(self) -> Result<Self::Output> {
8425        let Self {
8426            scope,
8427            elicitation_id,
8428            url,
8429        } = self;
8430        Ok(super::ElicitationUrlMode {
8431            scope: scope.into_v2()?,
8432            elicitation_id: elicitation_id.into_v2()?,
8433            url: url.into_v2()?,
8434        })
8435    }
8436}
8437
8438#[cfg(feature = "unstable_elicitation")]
8439impl IntoV1 for super::CreateElicitationResponse {
8440    type Output = crate::v1::CreateElicitationResponse;
8441
8442    fn into_v1(self) -> Result<Self::Output> {
8443        let Self { action, meta } = self;
8444        Ok(crate::v1::CreateElicitationResponse {
8445            action: action.into_v1()?,
8446            meta: meta.into_v1()?,
8447        })
8448    }
8449}
8450
8451#[cfg(feature = "unstable_elicitation")]
8452impl IntoV2 for crate::v1::CreateElicitationResponse {
8453    type Output = super::CreateElicitationResponse;
8454
8455    fn into_v2(self) -> Result<Self::Output> {
8456        let Self { action, meta } = self;
8457        Ok(super::CreateElicitationResponse {
8458            action: action.into_v2()?,
8459            meta: meta.into_v2()?,
8460        })
8461    }
8462}
8463
8464#[cfg(feature = "unstable_elicitation")]
8465impl IntoV1 for super::ElicitationAction {
8466    type Output = crate::v1::ElicitationAction;
8467
8468    fn into_v1(self) -> Result<Self::Output> {
8469        Ok(match self {
8470            Self::Accept(value) => crate::v1::ElicitationAction::Accept(value.into_v1()?),
8471            Self::Decline => crate::v1::ElicitationAction::Decline,
8472            Self::Cancel => crate::v1::ElicitationAction::Cancel,
8473            Self::Other(value) => crate::v1::ElicitationAction::Other(value.into_v1()?),
8474        })
8475    }
8476}
8477
8478#[cfg(feature = "unstable_elicitation")]
8479impl IntoV2 for crate::v1::ElicitationAction {
8480    type Output = super::ElicitationAction;
8481
8482    fn into_v2(self) -> Result<Self::Output> {
8483        Ok(match self {
8484            Self::Accept(value) => super::ElicitationAction::Accept(value.into_v2()?),
8485            Self::Decline => super::ElicitationAction::Decline,
8486            Self::Cancel => super::ElicitationAction::Cancel,
8487            Self::Other(value) => super::ElicitationAction::Other(value.into_v2()?),
8488        })
8489    }
8490}
8491
8492#[cfg(feature = "unstable_elicitation")]
8493impl IntoV1 for super::OtherElicitationAction {
8494    type Output = crate::v1::OtherElicitationAction;
8495
8496    fn into_v1(self) -> Result<Self::Output> {
8497        let Self { action, fields } = self;
8498        Ok(crate::v1::OtherElicitationAction {
8499            action: action.into_v1()?,
8500            fields: fields.into_v1()?,
8501        })
8502    }
8503}
8504
8505#[cfg(feature = "unstable_elicitation")]
8506impl IntoV2 for crate::v1::OtherElicitationAction {
8507    type Output = super::OtherElicitationAction;
8508
8509    fn into_v2(self) -> Result<Self::Output> {
8510        let Self { action, fields } = self;
8511        Ok(super::OtherElicitationAction {
8512            action: action.into_v2()?,
8513            fields: fields.into_v2()?,
8514        })
8515    }
8516}
8517
8518#[cfg(feature = "unstable_elicitation")]
8519impl IntoV1 for super::ElicitationAcceptAction {
8520    type Output = crate::v1::ElicitationAcceptAction;
8521
8522    fn into_v1(self) -> Result<Self::Output> {
8523        let Self { content } = self;
8524        Ok(crate::v1::ElicitationAcceptAction {
8525            content: content.into_v1()?,
8526        })
8527    }
8528}
8529
8530#[cfg(feature = "unstable_elicitation")]
8531impl IntoV2 for crate::v1::ElicitationAcceptAction {
8532    type Output = super::ElicitationAcceptAction;
8533
8534    fn into_v2(self) -> Result<Self::Output> {
8535        let Self { content } = self;
8536        Ok(super::ElicitationAcceptAction {
8537            content: content.into_v2()?,
8538        })
8539    }
8540}
8541
8542#[cfg(feature = "unstable_elicitation")]
8543impl IntoV1 for super::ElicitationContentValue {
8544    type Output = crate::v1::ElicitationContentValue;
8545
8546    fn into_v1(self) -> Result<Self::Output> {
8547        Ok(match self {
8548            Self::String(value) => crate::v1::ElicitationContentValue::String(value.into_v1()?),
8549            Self::Integer(value) => crate::v1::ElicitationContentValue::Integer(value.into_v1()?),
8550            Self::Number(value) => crate::v1::ElicitationContentValue::Number(value.into_v1()?),
8551            Self::Boolean(value) => crate::v1::ElicitationContentValue::Boolean(value.into_v1()?),
8552            Self::StringArray(value) => {
8553                crate::v1::ElicitationContentValue::StringArray(value.into_v1()?)
8554            }
8555        })
8556    }
8557}
8558
8559#[cfg(feature = "unstable_elicitation")]
8560impl IntoV2 for crate::v1::ElicitationContentValue {
8561    type Output = super::ElicitationContentValue;
8562
8563    fn into_v2(self) -> Result<Self::Output> {
8564        Ok(match self {
8565            Self::String(value) => super::ElicitationContentValue::String(value.into_v2()?),
8566            Self::Integer(value) => super::ElicitationContentValue::Integer(value.into_v2()?),
8567            Self::Number(value) => super::ElicitationContentValue::Number(value.into_v2()?),
8568            Self::Boolean(value) => super::ElicitationContentValue::Boolean(value.into_v2()?),
8569            Self::StringArray(value) => {
8570                super::ElicitationContentValue::StringArray(value.into_v2()?)
8571            }
8572        })
8573    }
8574}
8575
8576#[cfg(feature = "unstable_elicitation")]
8577impl IntoV1 for super::CompleteElicitationNotification {
8578    type Output = crate::v1::CompleteElicitationNotification;
8579
8580    fn into_v1(self) -> Result<Self::Output> {
8581        let Self {
8582            elicitation_id,
8583            meta,
8584        } = self;
8585        Ok(crate::v1::CompleteElicitationNotification {
8586            elicitation_id: elicitation_id.into_v1()?,
8587            meta: meta.into_v1()?,
8588        })
8589    }
8590}
8591
8592#[cfg(feature = "unstable_elicitation")]
8593impl IntoV2 for crate::v1::CompleteElicitationNotification {
8594    type Output = super::CompleteElicitationNotification;
8595
8596    fn into_v2(self) -> Result<Self::Output> {
8597        let Self {
8598            elicitation_id,
8599            meta,
8600        } = self;
8601        Ok(super::CompleteElicitationNotification {
8602            elicitation_id: elicitation_id.into_v2()?,
8603            meta: meta.into_v2()?,
8604        })
8605    }
8606}
8607
8608impl IntoV1 for super::ContentBlock {
8609    type Output = crate::v1::ContentBlock;
8610
8611    fn into_v1(self) -> Result<Self::Output> {
8612        Ok(match self {
8613            Self::Text(value) => crate::v1::ContentBlock::Text(value.into_v1()?),
8614            Self::Image(value) => crate::v1::ContentBlock::Image(value.into_v1()?),
8615            Self::Audio(value) => crate::v1::ContentBlock::Audio(value.into_v1()?),
8616            Self::ResourceLink(value) => crate::v1::ContentBlock::ResourceLink(value.into_v1()?),
8617            Self::Resource(value) => crate::v1::ContentBlock::Resource(value.into_v1()?),
8618            Self::Other(value) => {
8619                return Err(unknown_v2_enum_variant("ContentBlock", &value.type_));
8620            }
8621        })
8622    }
8623}
8624
8625impl IntoV2 for crate::v1::ContentBlock {
8626    type Output = super::ContentBlock;
8627
8628    fn into_v2(self) -> Result<Self::Output> {
8629        Ok(match self {
8630            Self::Text(value) => super::ContentBlock::Text(value.into_v2()?),
8631            Self::Image(value) => super::ContentBlock::Image(value.into_v2()?),
8632            Self::Audio(value) => super::ContentBlock::Audio(value.into_v2()?),
8633            Self::ResourceLink(value) => super::ContentBlock::ResourceLink(value.into_v2()?),
8634            Self::Resource(value) => super::ContentBlock::Resource(value.into_v2()?),
8635        })
8636    }
8637}
8638
8639impl IntoV1 for super::TextContent {
8640    type Output = crate::v1::TextContent;
8641
8642    fn into_v1(self) -> Result<Self::Output> {
8643        let Self {
8644            annotations,
8645            text,
8646            meta,
8647        } = self;
8648        Ok(crate::v1::TextContent {
8649            annotations: into_v1_default_on_error(annotations),
8650            text: text.into_v1()?,
8651            meta: meta.into_v1()?,
8652        })
8653    }
8654}
8655
8656impl IntoV2 for crate::v1::TextContent {
8657    type Output = super::TextContent;
8658
8659    fn into_v2(self) -> Result<Self::Output> {
8660        let Self {
8661            annotations,
8662            text,
8663            meta,
8664        } = self;
8665        Ok(super::TextContent {
8666            annotations: into_v2_default_on_error(annotations),
8667            text: text.into_v2()?,
8668            meta: meta.into_v2()?,
8669        })
8670    }
8671}
8672
8673impl IntoV1 for super::ImageContent {
8674    type Output = crate::v1::ImageContent;
8675
8676    fn into_v1(self) -> Result<Self::Output> {
8677        let Self {
8678            annotations,
8679            data,
8680            mime_type,
8681            uri,
8682            meta,
8683        } = self;
8684        Ok(crate::v1::ImageContent {
8685            annotations: into_v1_default_on_error(annotations),
8686            data: data.into_v1()?,
8687            mime_type: mime_type.into_v1()?,
8688            uri: uri.into_v1()?,
8689            meta: meta.into_v1()?,
8690        })
8691    }
8692}
8693
8694impl IntoV2 for crate::v1::ImageContent {
8695    type Output = super::ImageContent;
8696
8697    fn into_v2(self) -> Result<Self::Output> {
8698        let Self {
8699            annotations,
8700            data,
8701            mime_type,
8702            uri,
8703            meta,
8704        } = self;
8705        Ok(super::ImageContent {
8706            annotations: into_v2_default_on_error(annotations),
8707            data: data.into_v2()?,
8708            mime_type: mime_type.into_v2()?,
8709            uri: uri.into_v2()?,
8710            meta: meta.into_v2()?,
8711        })
8712    }
8713}
8714
8715impl IntoV1 for super::AudioContent {
8716    type Output = crate::v1::AudioContent;
8717
8718    fn into_v1(self) -> Result<Self::Output> {
8719        let Self {
8720            annotations,
8721            data,
8722            mime_type,
8723            meta,
8724        } = self;
8725        Ok(crate::v1::AudioContent {
8726            annotations: into_v1_default_on_error(annotations),
8727            data: data.into_v1()?,
8728            mime_type: mime_type.into_v1()?,
8729            meta: meta.into_v1()?,
8730        })
8731    }
8732}
8733
8734impl IntoV2 for crate::v1::AudioContent {
8735    type Output = super::AudioContent;
8736
8737    fn into_v2(self) -> Result<Self::Output> {
8738        let Self {
8739            annotations,
8740            data,
8741            mime_type,
8742            meta,
8743        } = self;
8744        Ok(super::AudioContent {
8745            annotations: into_v2_default_on_error(annotations),
8746            data: data.into_v2()?,
8747            mime_type: mime_type.into_v2()?,
8748            meta: meta.into_v2()?,
8749        })
8750    }
8751}
8752
8753impl IntoV1 for super::EmbeddedResource {
8754    type Output = crate::v1::EmbeddedResource;
8755
8756    fn into_v1(self) -> Result<Self::Output> {
8757        let Self {
8758            annotations,
8759            resource,
8760            meta,
8761        } = self;
8762        Ok(crate::v1::EmbeddedResource {
8763            annotations: into_v1_default_on_error(annotations),
8764            resource: resource.into_v1()?,
8765            meta: meta.into_v1()?,
8766        })
8767    }
8768}
8769
8770impl IntoV2 for crate::v1::EmbeddedResource {
8771    type Output = super::EmbeddedResource;
8772
8773    fn into_v2(self) -> Result<Self::Output> {
8774        let Self {
8775            annotations,
8776            resource,
8777            meta,
8778        } = self;
8779        Ok(super::EmbeddedResource {
8780            annotations: into_v2_default_on_error(annotations),
8781            resource: resource.into_v2()?,
8782            meta: meta.into_v2()?,
8783        })
8784    }
8785}
8786
8787impl IntoV1 for super::EmbeddedResourceResource {
8788    type Output = crate::v1::EmbeddedResourceResource;
8789
8790    fn into_v1(self) -> Result<Self::Output> {
8791        Ok(match self {
8792            Self::TextResourceContents(value) => {
8793                crate::v1::EmbeddedResourceResource::TextResourceContents(value.into_v1()?)
8794            }
8795            Self::BlobResourceContents(value) => {
8796                crate::v1::EmbeddedResourceResource::BlobResourceContents(value.into_v1()?)
8797            }
8798        })
8799    }
8800}
8801
8802impl IntoV2 for crate::v1::EmbeddedResourceResource {
8803    type Output = super::EmbeddedResourceResource;
8804
8805    fn into_v2(self) -> Result<Self::Output> {
8806        Ok(match self {
8807            Self::TextResourceContents(value) => {
8808                super::EmbeddedResourceResource::TextResourceContents(value.into_v2()?)
8809            }
8810            Self::BlobResourceContents(value) => {
8811                super::EmbeddedResourceResource::BlobResourceContents(value.into_v2()?)
8812            }
8813        })
8814    }
8815}
8816
8817impl IntoV1 for super::TextResourceContents {
8818    type Output = crate::v1::TextResourceContents;
8819
8820    fn into_v1(self) -> Result<Self::Output> {
8821        let Self {
8822            mime_type,
8823            text,
8824            uri,
8825            meta,
8826        } = self;
8827        Ok(crate::v1::TextResourceContents {
8828            mime_type: mime_type.into_v1()?,
8829            text: text.into_v1()?,
8830            uri: uri.into_v1()?,
8831            meta: meta.into_v1()?,
8832        })
8833    }
8834}
8835
8836impl IntoV2 for crate::v1::TextResourceContents {
8837    type Output = super::TextResourceContents;
8838
8839    fn into_v2(self) -> Result<Self::Output> {
8840        let Self {
8841            mime_type,
8842            text,
8843            uri,
8844            meta,
8845        } = self;
8846        Ok(super::TextResourceContents {
8847            mime_type: mime_type.into_v2()?,
8848            text: text.into_v2()?,
8849            uri: uri.into_v2()?,
8850            meta: meta.into_v2()?,
8851        })
8852    }
8853}
8854
8855impl IntoV1 for super::BlobResourceContents {
8856    type Output = crate::v1::BlobResourceContents;
8857
8858    fn into_v1(self) -> Result<Self::Output> {
8859        let Self {
8860            blob,
8861            mime_type,
8862            uri,
8863            meta,
8864        } = self;
8865        Ok(crate::v1::BlobResourceContents {
8866            blob: blob.into_v1()?,
8867            mime_type: mime_type.into_v1()?,
8868            uri: uri.into_v1()?,
8869            meta: meta.into_v1()?,
8870        })
8871    }
8872}
8873
8874impl IntoV2 for crate::v1::BlobResourceContents {
8875    type Output = super::BlobResourceContents;
8876
8877    fn into_v2(self) -> Result<Self::Output> {
8878        let Self {
8879            blob,
8880            mime_type,
8881            uri,
8882            meta,
8883        } = self;
8884        Ok(super::BlobResourceContents {
8885            blob: blob.into_v2()?,
8886            mime_type: mime_type.into_v2()?,
8887            uri: uri.into_v2()?,
8888            meta: meta.into_v2()?,
8889        })
8890    }
8891}
8892
8893impl IntoV1 for super::ResourceLink {
8894    type Output = crate::v1::ResourceLink;
8895
8896    fn into_v1(self) -> Result<Self::Output> {
8897        let Self {
8898            annotations,
8899            description,
8900            icons,
8901            mime_type,
8902            name,
8903            size,
8904            title,
8905            uri,
8906            meta,
8907        } = self;
8908
8909        if matches!(icons.as_ref(), Some(icons) if !icons.is_empty()) {
8910            return Err(ProtocolConversionError::new(
8911                "v2 ResourceLink.icons cannot be represented in v1",
8912            ));
8913        }
8914
8915        Ok(crate::v1::ResourceLink {
8916            annotations: into_v1_default_on_error(annotations),
8917            description: description.into_v1()?,
8918            mime_type: mime_type.into_v1()?,
8919            name: name.into_v1()?,
8920            size: size.into_v1()?,
8921            title: title.into_v1()?,
8922            uri: uri.into_v1()?,
8923            meta: meta.into_v1()?,
8924        })
8925    }
8926}
8927
8928impl IntoV2 for crate::v1::ResourceLink {
8929    type Output = super::ResourceLink;
8930
8931    fn into_v2(self) -> Result<Self::Output> {
8932        let Self {
8933            annotations,
8934            description,
8935            mime_type,
8936            name,
8937            size,
8938            title,
8939            uri,
8940            meta,
8941        } = self;
8942        Ok(super::ResourceLink {
8943            annotations: into_v2_default_on_error(annotations),
8944            description: description.into_v2()?,
8945            icons: None,
8946            mime_type: mime_type.into_v2()?,
8947            name: name.into_v2()?,
8948            size: size.into_v2()?,
8949            title: title.into_v2()?,
8950            uri: uri.into_v2()?,
8951            meta: meta.into_v2()?,
8952        })
8953    }
8954}
8955
8956impl IntoV1 for super::Annotations {
8957    type Output = crate::v1::Annotations;
8958
8959    fn into_v1(self) -> Result<Self::Output> {
8960        let Self {
8961            audience,
8962            last_modified,
8963            priority,
8964            meta,
8965        } = self;
8966        Ok(crate::v1::Annotations {
8967            audience: option_vec_into_v1_skip_errors(audience),
8968            last_modified: last_modified.into_v1()?,
8969            priority: priority.into_v1()?,
8970            meta: meta.into_v1()?,
8971        })
8972    }
8973}
8974
8975impl IntoV2 for crate::v1::Annotations {
8976    type Output = super::Annotations;
8977
8978    fn into_v2(self) -> Result<Self::Output> {
8979        let Self {
8980            audience,
8981            last_modified,
8982            priority,
8983            meta,
8984        } = self;
8985        Ok(super::Annotations {
8986            audience: option_vec_into_v2_skip_errors(audience),
8987            last_modified: last_modified.into_v2()?,
8988            priority: priority.into_v2()?,
8989            meta: meta.into_v2()?,
8990        })
8991    }
8992}
8993
8994impl IntoV1 for super::Role {
8995    type Output = crate::v1::Role;
8996
8997    fn into_v1(self) -> Result<Self::Output> {
8998        Ok(match self {
8999            Self::Assistant => crate::v1::Role::Assistant,
9000            Self::User => crate::v1::Role::User,
9001            Self::Other(value) => return Err(unknown_v2_enum_variant("Role", &value)),
9002        })
9003    }
9004}
9005
9006impl IntoV2 for crate::v1::Role {
9007    type Output = super::Role;
9008
9009    fn into_v2(self) -> Result<Self::Output> {
9010        Ok(match self {
9011            Self::Assistant => super::Role::Assistant,
9012            Self::User => super::Role::User,
9013        })
9014    }
9015}
9016
9017#[cfg(test)]
9018mod tests {
9019    use super::*;
9020    use crate::{v1, v2};
9021
9022    /// Round-trip a v1 value through v2 and back, asserting equality.
9023    ///
9024    /// This catches dropped fields, renamed fields, and missing enum
9025    /// variants in either direction of the conversion as soon as v1 and v2
9026    /// diverge.
9027    fn assert_v1_round_trip<T1, T2>(value: T1)
9028    where
9029        T1: IntoV2<Output = T2> + Clone + std::fmt::Debug + PartialEq,
9030        T2: IntoV1<Output = T1>,
9031    {
9032        let original = value.clone();
9033        let as_v2 = v1_to_v2(value).expect("v1 -> v2 conversion failed");
9034        let back = v2_to_v1(as_v2).expect("v2 -> v1 conversion failed");
9035        assert_eq!(
9036            original, back,
9037            "value did not survive v1 -> v2 -> v1 round trip"
9038        );
9039    }
9040
9041    /// Round-trip a v2 value through v1 and back, asserting equality.
9042    fn assert_v2_round_trip<T2, T1>(value: T2)
9043    where
9044        T2: IntoV1<Output = T1> + Clone + std::fmt::Debug + PartialEq,
9045        T1: IntoV2<Output = T2>,
9046    {
9047        let original = value.clone();
9048        let as_v1 = v2_to_v1(value).expect("v2 -> v1 conversion failed");
9049        let back = v1_to_v2(as_v1).expect("v1 -> v2 conversion failed");
9050        assert_eq!(
9051            original, back,
9052            "value did not survive v2 -> v1 -> v2 round trip"
9053        );
9054    }
9055
9056    /// While v1 and v2 are structurally identical, JSON produced by either
9057    /// module must be byte-equal after a conversion. This is a cheap insurance
9058    /// against accidental field renames or shape drift in conversions.
9059    ///
9060    /// Starts from a v1 value, converts forward to v2 and asserts JSON
9061    /// equality, then converts back to v1 and asserts JSON equality again.
9062    /// Catches shape drift in both directions of the conversion.
9063    fn assert_json_eq_after_v1_to_v2<T1, T2>(value: T1)
9064    where
9065        T1: IntoV2<Output = T2> + serde::Serialize + Clone,
9066        T2: IntoV1<Output = T1> + serde::Serialize,
9067    {
9068        let v1_json = serde_json::to_value(&value).expect("v1 serialize");
9069        let as_v2 = v1_to_v2(value).expect("v1 -> v2 conversion");
9070        let v2_json = serde_json::to_value(&as_v2).expect("v2 serialize");
9071        assert_eq!(
9072            v1_json, v2_json,
9073            "JSON shape diverged after v1 -> v2 conversion"
9074        );
9075
9076        let back_to_v1 = v2_to_v1(as_v2).expect("v2 -> v1 conversion");
9077        let v1_json_after =
9078            serde_json::to_value(&back_to_v1).expect("v1 serialize after round trip");
9079        assert_eq!(
9080            v2_json, v1_json_after,
9081            "JSON shape diverged after v2 -> v1 conversion"
9082        );
9083    }
9084
9085    /// Mirror of [`assert_json_eq_after_v1_to_v2`] that starts from a v2 value.
9086    /// Useful when the natural starting point is a v2 type (for example when
9087    /// the type only exists today in v2's draft API surface).
9088    fn assert_json_eq_after_v2_to_v1<T2, T1>(value: T2)
9089    where
9090        T2: IntoV1<Output = T1> + serde::Serialize + Clone,
9091        T1: IntoV2<Output = T2> + serde::Serialize,
9092    {
9093        let v2_json = serde_json::to_value(&value).expect("v2 serialize");
9094        let as_v1 = v2_to_v1(value).expect("v2 -> v1 conversion");
9095        let v1_json = serde_json::to_value(&as_v1).expect("v1 serialize");
9096        assert_eq!(
9097            v2_json, v1_json,
9098            "JSON shape diverged after v2 -> v1 conversion"
9099        );
9100
9101        let back_to_v2 = v1_to_v2(as_v1).expect("v1 -> v2 conversion");
9102        let v2_json_after =
9103            serde_json::to_value(&back_to_v2).expect("v2 serialize after round trip");
9104        assert_eq!(
9105            v1_json, v2_json_after,
9106            "JSON shape diverged after v1 -> v2 conversion"
9107        );
9108    }
9109
9110    fn assert_v2_to_v1_error<T>(value: T, expected: &str)
9111    where
9112        T: IntoV1,
9113        T::Output: std::fmt::Debug,
9114    {
9115        let error = v2_to_v1(value).unwrap_err();
9116        assert_eq!(error.message(), expected);
9117    }
9118
9119    fn assert_v2_to_v1_many_error<T>(value: T, expected: &str)
9120    where
9121        T: IntoV1Many,
9122        T::Output: std::fmt::Debug,
9123    {
9124        let error = v2_to_v1_many(value).unwrap_err();
9125        assert_eq!(error.message(), expected);
9126    }
9127
9128    fn assert_v1_to_v2_error<T>(value: T, expected: &str)
9129    where
9130        T: IntoV2,
9131        T::Output: std::fmt::Debug,
9132    {
9133        let error = v1_to_v2(value).unwrap_err();
9134        assert_eq!(error.message(), expected);
9135    }
9136
9137    #[test]
9138    fn round_trips_session_config_option_categories() {
9139        for category in [
9140            v1::SessionConfigOptionCategory::Mode,
9141            v1::SessionConfigOptionCategory::Model,
9142            v1::SessionConfigOptionCategory::ModelConfig,
9143            v1::SessionConfigOptionCategory::ThoughtLevel,
9144            v1::SessionConfigOptionCategory::Other("_custom_category".to_string()),
9145        ] {
9146            assert_v1_round_trip::<v1::SessionConfigOptionCategory, v2::SessionConfigOptionCategory>(
9147                category,
9148            );
9149        }
9150
9151        for category in [
9152            v2::SessionConfigOptionCategory::Mode,
9153            v2::SessionConfigOptionCategory::Model,
9154            v2::SessionConfigOptionCategory::ModelConfig,
9155            v2::SessionConfigOptionCategory::ThoughtLevel,
9156            v2::SessionConfigOptionCategory::Other("_custom_category".to_string()),
9157        ] {
9158            assert_v2_round_trip::<v2::SessionConfigOptionCategory, v1::SessionConfigOptionCategory>(
9159                category,
9160            );
9161        }
9162    }
9163
9164    #[test]
9165    fn converts_v2_initialize_request_to_v1_without_serde() {
9166        let request = v2::InitializeRequest::new(
9167            ProtocolVersion::V2,
9168            v2::Implementation::new("test-client", "1.0.0"),
9169        );
9170
9171        let converted: v1::InitializeRequest = v2_to_v1(request).unwrap();
9172
9173        assert_eq!(converted.protocol_version, ProtocolVersion::V2);
9174        assert_eq!(
9175            converted
9176                .client_info
9177                .as_ref()
9178                .map(|info| info.name.as_str()),
9179            Some("test-client")
9180        );
9181    }
9182
9183    #[test]
9184    fn v1_initialize_request_without_client_info_does_not_convert_to_v2() {
9185        let request = v1::InitializeRequest::new(ProtocolVersion::V1);
9186
9187        assert_v1_to_v2_error(
9188            request,
9189            "v1 InitializeRequest without `clientInfo` cannot be represented in v2",
9190        );
9191    }
9192
9193    #[test]
9194    fn v1_initialize_response_without_agent_info_does_not_convert_to_v2() {
9195        let response = v1::InitializeResponse::new(ProtocolVersion::V1);
9196
9197        assert_v1_to_v2_error(
9198            response,
9199            "v1 InitializeResponse without `agentInfo` cannot be represented in v2",
9200        );
9201    }
9202
9203    #[test]
9204    fn round_trips_initialize_request() {
9205        let client_capabilities = v1::ClientCapabilities::new().session(
9206            v1::ClientSessionCapabilities::new().config_options(
9207                v1::SessionConfigOptionsCapabilities::new()
9208                    .boolean(v1::BooleanConfigOptionCapabilities::new()),
9209            ),
9210        );
9211
9212        let request = v1::InitializeRequest::new(ProtocolVersion::V1)
9213            .client_capabilities(client_capabilities)
9214            .client_info(v1::Implementation::new("test-client", "1.0.0").title("Test Client"));
9215
9216        assert_v1_round_trip::<v1::InitializeRequest, v2::InitializeRequest>(request.clone());
9217        let converted: v2::InitializeRequest =
9218            v1_to_v2(request).expect("v1 -> v2 conversion failed");
9219        let converted_capabilities =
9220            serde_json::to_value(&converted.capabilities).expect("v2 serialize");
9221        assert_eq!(converted_capabilities.get("fs"), None);
9222        assert_eq!(converted_capabilities.get("terminal"), None);
9223        let converted_json = serde_json::to_value(&converted).expect("v2 serialize");
9224        assert_eq!(converted_json.get("clientInfo"), None);
9225        assert_eq!(converted_json.get("implementation"), None);
9226        assert!(converted_json.get("info").is_some());
9227    }
9228
9229    #[test]
9230    fn round_trips_initialize_response() {
9231        let session_capabilities = v1::SessionCapabilities::new()
9232            .list(v1::SessionListCapabilities::new())
9233            .resume(v1::SessionResumeCapabilities::new())
9234            .close(v1::SessionCloseCapabilities::new());
9235        let response = v1::InitializeResponse::new(ProtocolVersion::V1)
9236            .agent_capabilities(
9237                v1::AgentCapabilities::new()
9238                    .load_session(true)
9239                    .session_capabilities(session_capabilities)
9240                    .auth(v1::AgentAuthCapabilities::new().logout(v1::LogoutCapabilities::new())),
9241            )
9242            .agent_info(v1::Implementation::new("test-agent", "2.0.0").title("Test Agent"));
9243        assert_v1_round_trip::<v1::InitializeResponse, v2::InitializeResponse>(response.clone());
9244        let converted: v2::InitializeResponse =
9245            v1_to_v2(response).expect("v1 -> v2 conversion failed");
9246        let converted_json = serde_json::to_value(&converted).expect("v2 serialize");
9247        assert_eq!(converted_json.get("agentCapabilities"), None);
9248        assert!(converted_json.get("capabilities").is_some());
9249        assert_eq!(converted_json.get("agentInfo"), None);
9250        assert_eq!(converted_json.get("implementation"), None);
9251        assert!(converted_json.get("info").is_some());
9252        assert_eq!(converted_json.pointer("/capabilities/loadSession"), None);
9253    }
9254
9255    #[test]
9256    fn required_v2_session_methods_convert_to_v1_capability_markers() {
9257        let v1_capabilities = v1::AgentCapabilities::new().load_session(true);
9258
9259        let v2_capabilities: v2::AgentCapabilities =
9260            v1_to_v2(v1_capabilities).expect("v1 -> v2 conversion");
9261        let session = v2_capabilities
9262            .session
9263            .as_ref()
9264            .expect("v1 capabilities imply v2 session support");
9265        assert!(session.delete.is_none());
9266        let v2_json = serde_json::to_value(&v2_capabilities).expect("v2 serialize");
9267        assert_eq!(v2_json.get("loadSession"), None);
9268        assert_eq!(v2_json.pointer("/session/load"), None);
9269        assert_eq!(v2_json.pointer("/session/list"), None);
9270        assert_eq!(v2_json.pointer("/session/resume"), None);
9271        assert_eq!(v2_json.pointer("/session/close"), None);
9272
9273        let v1_after: v1::AgentCapabilities =
9274            v2_to_v1(v2_capabilities).expect("v2 -> v1 conversion");
9275        assert!(v1_after.load_session);
9276        assert!(v1_after.session_capabilities.list.is_some());
9277        assert!(v1_after.session_capabilities.resume.is_some());
9278        assert!(v1_after.session_capabilities.close.is_some());
9279    }
9280
9281    #[test]
9282    fn v2_agent_capabilities_without_session_do_not_convert_to_v1() {
9283        let error = v2::AgentCapabilities::new().into_v1().unwrap_err();
9284        assert_eq!(
9285            error.message(),
9286            "v2 AgentCapabilities without `session` cannot be represented in v1"
9287        );
9288    }
9289
9290    #[test]
9291    fn v2_auth_logout_is_baseline_not_capability_marker() {
9292        let v2_auth = v2::AgentAuthCapabilities::new();
9293        let v2_json = serde_json::to_value(&v2_auth).expect("v2 serialize");
9294        assert_eq!(v2_json.get("logout"), None);
9295
9296        let v1_auth: v1::AgentAuthCapabilities = v2_to_v1(v2_auth).expect("v2 -> v1 conversion");
9297        assert!(v1_auth.logout.is_some());
9298
9299        let v1_auth_without_logout = v1::AgentAuthCapabilities::new();
9300        let v2_auth: v2::AgentAuthCapabilities =
9301            v1_to_v2(v1_auth_without_logout).expect("v1 -> v2 conversion");
9302        let v2_json = serde_json::to_value(&v2_auth).expect("v2 serialize");
9303        assert_eq!(v2_json.get("logout"), None);
9304    }
9305
9306    #[test]
9307    fn v2_session_capabilities_convert_to_v1_agent_capability_parts() {
9308        let parts = v2::SessionCapabilities::new()
9309            .prompt(v2::PromptCapabilities::new().image(v2::PromptImageCapabilities::new()))
9310            .mcp(v2::McpCapabilities::new().http(v2::McpHttpCapabilities::new()))
9311            .into_v1()
9312            .expect("v2 session capabilities -> v1 parts");
9313
9314        assert!(parts.session_capabilities.list.is_some());
9315        assert!(parts.session_capabilities.resume.is_some());
9316        assert!(parts.session_capabilities.close.is_some());
9317        assert!(parts.prompt_capabilities.image);
9318        assert!(parts.load_session);
9319        assert!(parts.mcp_capabilities.http);
9320    }
9321
9322    #[test]
9323    fn v1_prompt_capability_bools_convert_to_v2_objects() {
9324        let v1_capabilities = v1::PromptCapabilities::new()
9325            .image(true)
9326            .audio(true)
9327            .embedded_context(true);
9328
9329        let v2_capabilities: v2::PromptCapabilities =
9330            v1_to_v2(v1_capabilities).expect("v1 -> v2 conversion");
9331        let v2_json = serde_json::to_value(&v2_capabilities).expect("v2 serialize");
9332        assert_eq!(v2_json.pointer("/image"), Some(&serde_json::json!({})));
9333        assert_eq!(v2_json.pointer("/audio"), Some(&serde_json::json!({})));
9334        assert_eq!(
9335            v2_json.pointer("/embeddedContext"),
9336            Some(&serde_json::json!({}))
9337        );
9338
9339        let v1_after: v1::PromptCapabilities =
9340            v2_to_v1(v2_capabilities).expect("v2 -> v1 conversion");
9341        assert!(v1_after.image);
9342        assert!(v1_after.audio);
9343        assert!(v1_after.embedded_context);
9344    }
9345
9346    #[test]
9347    fn v1_mcp_capabilities_convert_to_v2_transport_objects() {
9348        let v1_capabilities = v1::McpCapabilities::new().http(true).sse(true);
9349
9350        let v2_capabilities: v2::McpCapabilities =
9351            v1_to_v2(v1_capabilities).expect("v1 -> v2 conversion");
9352        let v2_json = serde_json::to_value(&v2_capabilities).expect("v2 serialize");
9353        assert_eq!(v2_json.pointer("/stdio"), Some(&serde_json::json!({})));
9354        assert_eq!(v2_json.pointer("/http"), Some(&serde_json::json!({})));
9355        assert_eq!(v2_json.pointer("/sse"), None);
9356
9357        let v1_after: v1::McpCapabilities = v2_to_v1(v2_capabilities).expect("v2 -> v1 conversion");
9358        assert!(v1_after.http);
9359        assert!(!v1_after.sse);
9360    }
9361
9362    #[cfg(feature = "unstable_mcp_over_acp")]
9363    #[test]
9364    fn v1_mcp_acp_capability_bool_converts_to_v2_object() {
9365        let v1_capabilities = v1::McpCapabilities::new().acp(true);
9366
9367        let v2_capabilities: v2::McpCapabilities =
9368            v1_to_v2(v1_capabilities).expect("v1 -> v2 conversion");
9369        let v2_json = serde_json::to_value(&v2_capabilities).expect("v2 serialize");
9370        assert_eq!(v2_json.pointer("/acp"), Some(&serde_json::json!({})));
9371
9372        let v1_after: v1::McpCapabilities = v2_to_v1(v2_capabilities).expect("v2 -> v1 conversion");
9373        assert!(v1_after.acp);
9374    }
9375
9376    #[cfg(feature = "unstable_auth_methods")]
9377    #[test]
9378    fn v1_auth_terminal_capability_bool_converts_to_v2_object() {
9379        let v1_capabilities = v1::AuthCapabilities::new().terminal(true);
9380
9381        let v2_capabilities: v2::AuthCapabilities =
9382            v1_to_v2(v1_capabilities).expect("v1 -> v2 conversion");
9383        let v2_json = serde_json::to_value(&v2_capabilities).expect("v2 serialize");
9384        assert_eq!(v2_json.pointer("/terminal"), Some(&serde_json::json!({})));
9385
9386        let v1_after: v1::AuthCapabilities =
9387            v2_to_v1(v2_capabilities).expect("v2 -> v1 conversion");
9388        assert!(v1_after.terminal);
9389    }
9390
9391    #[cfg(feature = "unstable_auth_methods")]
9392    #[test]
9393    fn auth_method_terminal_env_converts_between_map_and_variable_array() {
9394        let mut env = HashMap::new();
9395        env.insert("TERM".to_string(), "xterm-256color".to_string());
9396        env.insert("API_KEY".to_string(), "secret".to_string());
9397
9398        let v1_method = v1::AuthMethodTerminal::new("tui-auth", "Terminal Auth").env(env);
9399        let v2_method: v2::AuthMethodTerminal = v1_to_v2(v1_method).expect("v1 -> v2 conversion");
9400        let v2_json = serde_json::to_value(&v2_method).expect("v2 serialize");
9401        assert_eq!(
9402            v2_json.pointer("/env"),
9403            Some(&serde_json::json!([
9404                {
9405                    "name": "API_KEY",
9406                    "value": "secret"
9407                },
9408                {
9409                    "name": "TERM",
9410                    "value": "xterm-256color"
9411                }
9412            ]))
9413        );
9414
9415        let v1_after: v1::AuthMethodTerminal = v2_to_v1(v2_method).expect("v2 -> v1 conversion");
9416        assert_eq!(
9417            v1_after.env.get("TERM").map(String::as_str),
9418            Some("xterm-256color")
9419        );
9420        assert_eq!(
9421            v1_after.env.get("API_KEY").map(String::as_str),
9422            Some("secret")
9423        );
9424    }
9425
9426    #[cfg(feature = "unstable_auth_methods")]
9427    #[test]
9428    fn auth_method_terminal_duplicate_env_names_do_not_convert_to_v1() {
9429        let v2_method = v2::AuthMethodTerminal::new("tui-auth", "Terminal Auth").env(vec![
9430            v2::EnvVariable::new("TERM", "xterm"),
9431            v2::EnvVariable::new("TERM", "xterm-256color"),
9432        ]);
9433
9434        assert_v2_to_v1_error(
9435            v2_method,
9436            "v2 AuthMethodTerminal env variable `TERM` is duplicated and cannot be represented in v1",
9437        );
9438    }
9439
9440    #[test]
9441    fn v1_client_fs_and_terminal_capabilities_are_removed_in_v2() {
9442        let v1_capabilities =
9443            v1::ClientCapabilities::new()
9444                .terminal(true)
9445                .fs(v1::FileSystemCapabilities::new()
9446                    .read_text_file(true)
9447                    .write_text_file(true));
9448
9449        let v2_capabilities: v2::ClientCapabilities =
9450            v1_to_v2(v1_capabilities).expect("v1 -> v2 conversion");
9451        let v2_json = serde_json::to_value(&v2_capabilities).expect("v2 serialize");
9452        assert_eq!(
9453            v2_json.get("fs"),
9454            None,
9455            "v2 ClientCapabilities must not include filesystem capabilities"
9456        );
9457        assert_eq!(
9458            v2_json.get("terminal"),
9459            None,
9460            "v2 ClientCapabilities must not include terminal capabilities"
9461        );
9462
9463        let v1_after: v1::ClientCapabilities =
9464            v2_to_v1(v2_capabilities).expect("v2 -> v1 conversion");
9465        assert!(!v1_after.fs.read_text_file);
9466        assert!(!v1_after.fs.write_text_file);
9467        assert!(!v1_after.terminal);
9468    }
9469
9470    #[test]
9471    fn v2_client_capabilities_default_to_v1_boolean_config_option_support() {
9472        let v2_capabilities = v2::ClientCapabilities::new();
9473
9474        let v1_capabilities: v1::ClientCapabilities =
9475            v2_to_v1(v2_capabilities).expect("v2 -> v1 conversion");
9476
9477        assert!(
9478            v1_capabilities
9479                .session
9480                .and_then(|session| session.config_options)
9481                .and_then(|config_options| config_options.boolean)
9482                .is_some()
9483        );
9484    }
9485
9486    #[test]
9487    fn v1_client_fs_and_terminal_methods_do_not_convert_to_v2() {
9488        assert_v1_to_v2_error(
9489            v1::AgentRequest::WriteTextFileRequest(v1::WriteTextFileRequest::new(
9490                "sess",
9491                "/workspace/file.txt",
9492                "contents",
9493            )),
9494            "v1 AgentRequest variant `fs/write_text_file` cannot be represented in v2",
9495        );
9496        assert_v1_to_v2_error(
9497            v1::AgentRequest::ReadTextFileRequest(v1::ReadTextFileRequest::new(
9498                "sess",
9499                "/workspace/file.txt",
9500            )),
9501            "v1 AgentRequest variant `fs/read_text_file` cannot be represented in v2",
9502        );
9503        assert_v1_to_v2_error(
9504            v1::AgentRequest::CreateTerminalRequest(v1::CreateTerminalRequest::new("sess", "echo")),
9505            "v1 AgentRequest variant `terminal/create` cannot be represented in v2",
9506        );
9507        assert_v1_to_v2_error(
9508            v1::AgentRequest::TerminalOutputRequest(v1::TerminalOutputRequest::new("sess", "term")),
9509            "v1 AgentRequest variant `terminal/output` cannot be represented in v2",
9510        );
9511        assert_v1_to_v2_error(
9512            v1::AgentRequest::ReleaseTerminalRequest(v1::ReleaseTerminalRequest::new(
9513                "sess", "term",
9514            )),
9515            "v1 AgentRequest variant `terminal/release` cannot be represented in v2",
9516        );
9517        assert_v1_to_v2_error(
9518            v1::AgentRequest::WaitForTerminalExitRequest(v1::WaitForTerminalExitRequest::new(
9519                "sess", "term",
9520            )),
9521            "v1 AgentRequest variant `terminal/wait_for_exit` cannot be represented in v2",
9522        );
9523        assert_v1_to_v2_error(
9524            v1::AgentRequest::KillTerminalRequest(v1::KillTerminalRequest::new("sess", "term")),
9525            "v1 AgentRequest variant `terminal/kill` cannot be represented in v2",
9526        );
9527
9528        assert_v1_to_v2_error(
9529            v1::ClientResponse::WriteTextFileResponse(v1::WriteTextFileResponse::new()),
9530            "v1 ClientResponse variant `fs/write_text_file` cannot be represented in v2",
9531        );
9532        assert_v1_to_v2_error(
9533            v1::ClientResponse::ReadTextFileResponse(v1::ReadTextFileResponse::new("contents")),
9534            "v1 ClientResponse variant `fs/read_text_file` cannot be represented in v2",
9535        );
9536        assert_v1_to_v2_error(
9537            v1::ClientResponse::CreateTerminalResponse(v1::CreateTerminalResponse::new("term")),
9538            "v1 ClientResponse variant `terminal/create` cannot be represented in v2",
9539        );
9540        assert_v1_to_v2_error(
9541            v1::ClientResponse::TerminalOutputResponse(v1::TerminalOutputResponse::new("", false)),
9542            "v1 ClientResponse variant `terminal/output` cannot be represented in v2",
9543        );
9544        assert_v1_to_v2_error(
9545            v1::ClientResponse::ReleaseTerminalResponse(v1::ReleaseTerminalResponse::new()),
9546            "v1 ClientResponse variant `terminal/release` cannot be represented in v2",
9547        );
9548        assert_v1_to_v2_error(
9549            v1::ClientResponse::WaitForTerminalExitResponse(v1::WaitForTerminalExitResponse::new(
9550                v1::TerminalExitStatus::new(),
9551            )),
9552            "v1 ClientResponse variant `terminal/wait_for_exit` cannot be represented in v2",
9553        );
9554        assert_v1_to_v2_error(
9555            v1::ClientResponse::KillTerminalResponse(v1::KillTerminalResponse::new()),
9556            "v1 ClientResponse variant `terminal/kill` cannot be represented in v2",
9557        );
9558    }
9559
9560    #[test]
9561    fn v1_terminal_tool_call_content_does_not_convert_to_v2() {
9562        assert_v1_to_v2_error(
9563            v1::ToolCallContent::Terminal(v1::Terminal::new("term")),
9564            "v1 ToolCallContent variant `terminal` cannot be represented in v2",
9565        );
9566    }
9567
9568    #[test]
9569    fn v1_mcp_sse_transport_does_not_convert_to_v2() {
9570        assert_v1_to_v2_error(
9571            v1::McpServer::Sse(v1::McpServerSse::new("events", "https://example.com/sse")),
9572            "v1 McpServer variant `sse` cannot be represented in v2",
9573        );
9574    }
9575
9576    #[test]
9577    fn v2_unknown_mcp_transport_does_not_convert_to_v1() {
9578        assert_v2_to_v1_error(
9579            v2::McpServer::Other(v2::OtherMcpServer::new("websocket", BTreeMap::default())),
9580            "v2 McpServer variant `websocket` cannot be represented in v1",
9581        );
9582    }
9583
9584    #[test]
9585    fn round_trips_new_session_request_with_mcp_variants() {
9586        let request = v1::NewSessionRequest::new("/workspace").mcp_servers(vec![
9587            v1::McpServer::Stdio(v1::McpServerStdio::new("local", "/usr/bin/mcp")),
9588            v1::McpServer::Http(v1::McpServerHttp::new("remote", "https://example.com")),
9589        ]);
9590
9591        assert_v1_round_trip::<v1::NewSessionRequest, v2::NewSessionRequest>(request.clone());
9592
9593        let v2_request: v2::NewSessionRequest = v1_to_v2(request).expect("v1 -> v2 conversion");
9594        assert_eq!(
9595            serde_json::to_value(&v2_request).expect("v2 serialize"),
9596            serde_json::json!({
9597                "cwd": "/workspace",
9598                "mcpServers": [
9599                    {
9600                        "type": "stdio",
9601                        "name": "local",
9602                        "command": "/usr/bin/mcp"
9603                    },
9604                    {
9605                        "type": "http",
9606                        "name": "remote",
9607                        "url": "https://example.com"
9608                    }
9609                ]
9610            })
9611        );
9612    }
9613
9614    #[test]
9615    fn round_trips_prompt_request_with_content_variants() {
9616        let prompt = vec![
9617            v1::ContentBlock::Text(v1::TextContent::new("hello")),
9618            v1::ContentBlock::Image(v1::ImageContent::new("data", "image/png")),
9619            v1::ContentBlock::ResourceLink(v1::ResourceLink::new("file.txt", "file:///file.txt")),
9620        ];
9621        let request = v1::PromptRequest::new("sess_1", prompt);
9622        assert_v1_round_trip::<v1::PromptRequest, v2::PromptRequest>(request.clone());
9623        assert_json_eq_after_v1_to_v2::<v1::PromptRequest, v2::PromptRequest>(request);
9624    }
9625
9626    #[cfg(feature = "unstable_elicitation")]
9627    #[test]
9628    fn round_trips_elicitation_property_schema_unknown_type() {
9629        let v1_schema = v1::ElicitationSchema::new().property(
9630            "location",
9631            v1::ElicitationPropertySchema::Other(v1::OtherElicitationPropertySchema::new(
9632                "_location",
9633                std::collections::BTreeMap::from([(
9634                    "precision".to_string(),
9635                    serde_json::json!("city"),
9636                )]),
9637            )),
9638            false,
9639        );
9640
9641        assert_v1_round_trip::<v1::ElicitationSchema, v2::ElicitationSchema>(v1_schema.clone());
9642        assert_json_eq_after_v1_to_v2::<v1::ElicitationSchema, v2::ElicitationSchema>(v1_schema);
9643
9644        let v2_schema = v2::ElicitationSchema::new().property(
9645            "location",
9646            v2::ElicitationPropertySchema::Other(v2::OtherElicitationPropertySchema::new(
9647                "_location",
9648                std::collections::BTreeMap::from([(
9649                    "precision".to_string(),
9650                    serde_json::json!("city"),
9651                )]),
9652            )),
9653            false,
9654        );
9655
9656        assert_v2_round_trip::<v2::ElicitationSchema, v1::ElicitationSchema>(v2_schema);
9657    }
9658
9659    #[cfg(feature = "unstable_elicitation")]
9660    #[test]
9661    fn round_trips_multi_select_items_unknown_type() {
9662        let v1_items = v1::MultiSelectItems::Other(v1::OtherMultiSelectItems::new(
9663            "_token",
9664            std::collections::BTreeMap::from([
9665                ("format".to_string(), serde_json::json!("workspace")),
9666                (
9667                    "anyOf".to_string(),
9668                    serde_json::json!([{ "const": "repo", "title": "Repository" }]),
9669                ),
9670            ]),
9671        ));
9672
9673        assert_v1_round_trip::<v1::MultiSelectItems, v2::MultiSelectItems>(v1_items.clone());
9674        assert_json_eq_after_v1_to_v2::<v1::MultiSelectItems, v2::MultiSelectItems>(v1_items);
9675
9676        let v2_items = v2::MultiSelectItems::Other(v2::OtherMultiSelectItems::new(
9677            "_token",
9678            std::collections::BTreeMap::from([
9679                ("format".to_string(), serde_json::json!("workspace")),
9680                (
9681                    "anyOf".to_string(),
9682                    serde_json::json!([{ "const": "repo", "title": "Repository" }]),
9683                ),
9684            ]),
9685        ));
9686
9687        assert_v2_round_trip::<v2::MultiSelectItems, v1::MultiSelectItems>(v2_items);
9688    }
9689
9690    #[cfg(feature = "unstable_elicitation")]
9691    #[test]
9692    fn round_trips_elicitation_mode_unknown_type() {
9693        let v1_request = v1::CreateElicitationRequest::new(
9694            v1::OtherElicitationMode::new(
9695                "_browser",
9696                v1::ElicitationRequestScope::new(v1::RequestId::Number(42)),
9697                std::collections::BTreeMap::from([(
9698                    "target".to_string(),
9699                    serde_json::json!("login"),
9700                )]),
9701            ),
9702            "Open a browser window",
9703        );
9704
9705        assert_v1_round_trip::<v1::CreateElicitationRequest, v2::CreateElicitationRequest>(
9706            v1_request.clone(),
9707        );
9708        assert_json_eq_after_v1_to_v2::<v1::CreateElicitationRequest, v2::CreateElicitationRequest>(
9709            v1_request,
9710        );
9711
9712        let v2_request = v2::CreateElicitationRequest::new(
9713            v2::OtherElicitationMode::new(
9714                "_browser",
9715                v2::ElicitationRequestScope::new(v2::RequestId::Number(42)),
9716                std::collections::BTreeMap::from([(
9717                    "target".to_string(),
9718                    serde_json::json!("login"),
9719                )]),
9720            ),
9721            "Open a browser window",
9722        );
9723
9724        assert_v2_round_trip::<v2::CreateElicitationRequest, v1::CreateElicitationRequest>(
9725            v2_request,
9726        );
9727    }
9728
9729    #[cfg(feature = "unstable_elicitation")]
9730    #[test]
9731    fn round_trips_elicitation_action_unknown_type() {
9732        let v1_response = v1::CreateElicitationResponse::new(v1::OtherElicitationAction::new(
9733            "_defer",
9734            std::collections::BTreeMap::from([
9735                ("reason".to_string(), serde_json::json!("waiting")),
9736                ("retryAfterMs".to_string(), serde_json::json!(1000)),
9737            ]),
9738        ));
9739
9740        assert_v1_round_trip::<v1::CreateElicitationResponse, v2::CreateElicitationResponse>(
9741            v1_response.clone(),
9742        );
9743        assert_json_eq_after_v1_to_v2::<v1::CreateElicitationResponse, v2::CreateElicitationResponse>(
9744            v1_response,
9745        );
9746
9747        let v2_response = v2::CreateElicitationResponse::new(v2::OtherElicitationAction::new(
9748            "_defer",
9749            std::collections::BTreeMap::from([
9750                ("reason".to_string(), serde_json::json!("waiting")),
9751                ("retryAfterMs".to_string(), serde_json::json!(1000)),
9752            ]),
9753        ));
9754
9755        assert_v2_round_trip::<v2::CreateElicitationResponse, v1::CreateElicitationResponse>(
9756            v2_response,
9757        );
9758    }
9759
9760    #[test]
9761    fn prompt_responses_do_not_convert_across_v1_v2_lifecycle_boundary() {
9762        assert_v2_to_v1_error(
9763            v2::PromptResponse::new(),
9764            "v2 PromptResponse cannot be represented in v1 because v2 reports completion with state_update session updates",
9765        );
9766        assert_v1_to_v2_error(
9767            v1::PromptResponse::new(v1::StopReason::EndTurn),
9768            "v1 PromptResponse cannot be represented in v2 by itself because v2 reports completion with state_update session updates",
9769        );
9770    }
9771
9772    #[test]
9773    fn v1_tool_call_converts_to_v2_upsert_with_diff_and_locations() {
9774        let tool_call = v1::ToolCall::new("tc_1", "editing files")
9775            .kind(v1::ToolKind::Edit)
9776            .status(v1::ToolCallStatus::InProgress)
9777            .content(vec![v1::ToolCallContent::Diff(
9778                v1::Diff::new("/path", "new contents").old_text("old contents"),
9779            )])
9780            .locations(vec![v1::ToolCallLocation::new("/path").line(42)])
9781            .raw_input(serde_json::json!({"foo": "bar"}))
9782            .raw_output(serde_json::json!({"ok": true}));
9783
9784        let converted: v2::ToolCallUpdate = v1_to_v2(tool_call).expect("v1 -> v2 conversion");
9785        assert_eq!(
9786            serde_json::to_value(&converted).expect("v2 serialize"),
9787            serde_json::json!({
9788                "toolCallId": "tc_1",
9789                "title": "editing files",
9790                "kind": "edit",
9791                "status": "in_progress",
9792                "content": [
9793                    {
9794                        "type": "diff",
9795                        "changes": [
9796                            {
9797                                "operation": "modify",
9798                                "path": "/path",
9799                                "fileType": "text"
9800                            }
9801                        ],
9802                        "patch": {
9803                            "format": "git_patch",
9804                            "diff": "diff --git /path /path\n--- /path\n+++ /path\n@@ -1 +1 @@\n-old contents\n\\ No newline at end of file\n+new contents\n\\ No newline at end of file\n"
9805                        }
9806                    }
9807                ],
9808                "locations": [
9809                    {
9810                        "path": "/path",
9811                        "line": 42
9812                    }
9813                ],
9814                "rawInput": {
9815                    "foo": "bar"
9816                },
9817                "rawOutput": {
9818                    "ok": true
9819                }
9820            })
9821        );
9822
9823        let back: v1::ToolCallUpdate = v2_to_v1(converted).expect("v2 -> v1 conversion");
9824        assert_eq!(back.tool_call_id.0.as_ref(), "tc_1");
9825        assert_eq!(back.fields.title.as_deref(), Some("editing files"));
9826        assert_eq!(back.fields.kind, Some(v1::ToolKind::Edit));
9827        assert_eq!(back.fields.status, Some(v1::ToolCallStatus::InProgress));
9828        assert_eq!(back.fields.content.as_ref().map(Vec::len), Some(0));
9829        assert_eq!(back.fields.locations.as_ref().map(Vec::len), Some(1));
9830        assert_eq!(
9831            back.fields.raw_input,
9832            Some(serde_json::json!({"foo": "bar"}))
9833        );
9834        assert_eq!(
9835            back.fields.raw_output,
9836            Some(serde_json::json!({"ok": true}))
9837        );
9838    }
9839
9840    #[test]
9841    fn v1_tool_call_update_round_trips_through_v2_tool_call_update_upsert() {
9842        let update = v1::ToolCallUpdate::new(
9843            "tc",
9844            v1::ToolCallUpdateFields::new()
9845                .status(v1::ToolCallStatus::Completed)
9846                .content(Vec::new()),
9847        );
9848
9849        assert_v1_round_trip::<v1::ToolCallUpdate, v2::ToolCallUpdate>(update.clone());
9850        assert_json_eq_after_v1_to_v2::<v1::ToolCallUpdate, v2::ToolCallUpdate>(update);
9851    }
9852
9853    #[test]
9854    fn v2_entity_meta_null_does_not_convert_to_v1() {
9855        assert_v2_to_v1_error(
9856            v2::SessionInfoUpdate::new().meta(None::<v2::Meta>),
9857            "v2 SessionInfoUpdate with null _meta cannot be represented in v1",
9858        );
9859        assert_v2_to_v1_error(
9860            v2::ToolCallUpdate::new("tc").meta(None::<v2::Meta>),
9861            "v2 ToolCallUpdate with null _meta cannot be represented in v1",
9862        );
9863    }
9864
9865    #[test]
9866    fn round_trips_session_notification_for_unchanged_update_kinds() {
9867        fn content_chunk(text: &str, message_id: &str) -> v1::ContentChunk {
9868            let chunk = v1::ContentChunk::new(v1::ContentBlock::Text(v1::TextContent::new(text)));
9869            chunk.message_id(message_id)
9870        }
9871
9872        let cases: Vec<v1::SessionUpdate> = vec![
9873            v1::SessionUpdate::UserMessageChunk(content_chunk("u", "msg_user")),
9874            v1::SessionUpdate::AgentMessageChunk(content_chunk("a", "msg_agent")),
9875            v1::SessionUpdate::AgentThoughtChunk(content_chunk("t", "msg_thought")),
9876            v1::SessionUpdate::SessionInfoUpdate(v1::SessionInfoUpdate::new().title("hi")),
9877            v1::SessionUpdate::UsageUpdate(
9878                v1::UsageUpdate::new(53_000, 200_000).cost(v1::Cost::new(0.045, "USD")),
9879            ),
9880        ];
9881        for update in cases {
9882            let notification = v1::SessionNotification::new("sess", update);
9883            let original_json = serde_json::to_value(&notification).expect("v1 serialize");
9884            let as_v2: v2::UpdateSessionNotification =
9885                v1_to_v2(notification.clone()).expect("v1 -> v2 conversion");
9886            let v2_json = serde_json::to_value(&as_v2).expect("v2 serialize");
9887            assert_eq!(
9888                original_json, v2_json,
9889                "JSON shape diverged after v1 -> v2 conversion"
9890            );
9891
9892            let back = v2_to_v1_many(as_v2).expect("v2 -> v1 conversion");
9893            assert_eq!(back, vec![notification]);
9894            let back_json = serde_json::to_value(&back[0]).expect("v1 serialize after round trip");
9895            assert_eq!(
9896                original_json, back_json,
9897                "JSON shape diverged after v2 -> v1 conversion"
9898            );
9899        }
9900    }
9901
9902    #[test]
9903    fn v1_tool_call_session_updates_convert_to_unified_v2_tool_call_update() {
9904        let create = v1::SessionNotification::new(
9905            "sess",
9906            v1::SessionUpdate::ToolCall(v1::ToolCall::new("tc", "title")),
9907        );
9908        let create_v2: v2::UpdateSessionNotification =
9909            v1_to_v2(create).expect("v1 -> v2 conversion");
9910        assert!(matches!(
9911            create_v2.update,
9912            v2::SessionUpdate::ToolCallUpdate(_)
9913        ));
9914        assert_eq!(
9915            serde_json::to_value(&create_v2).expect("v2 serialize"),
9916            serde_json::json!({
9917                "sessionId": "sess",
9918                "update": {
9919                    "sessionUpdate": "tool_call_update",
9920                    "toolCallId": "tc",
9921                    "title": "title"
9922                }
9923            })
9924        );
9925
9926        let update = v1::SessionNotification::new(
9927            "sess",
9928            v1::SessionUpdate::ToolCallUpdate(v1::ToolCallUpdate::new(
9929                "tc",
9930                v1::ToolCallUpdateFields::new().status(v1::ToolCallStatus::Completed),
9931            )),
9932        );
9933        let update_v2: v2::UpdateSessionNotification =
9934            v1_to_v2(update).expect("v1 -> v2 conversion");
9935        assert!(matches!(
9936            update_v2.update,
9937            v2::SessionUpdate::ToolCallUpdate(_)
9938        ));
9939        assert_eq!(
9940            serde_json::to_value(&update_v2).expect("v2 serialize"),
9941            serde_json::json!({
9942                "sessionId": "sess",
9943                "update": {
9944                    "sessionUpdate": "tool_call_update",
9945                    "toolCallId": "tc",
9946                    "status": "completed"
9947                }
9948            })
9949        );
9950    }
9951
9952    #[test]
9953    fn v2_full_messages_convert_to_v1_message_chunks() {
9954        let mut meta = v2::Meta::new();
9955        meta.insert("source".to_string(), serde_json::json!("full"));
9956
9957        let chunks = v2_to_v1_many(v2::SessionUpdate::UserMessage(
9958            v2::UserMessage::new("msg_user")
9959                .content(vec![
9960                    v2::ContentBlock::Text(v2::TextContent::new("hello")),
9961                    v2::ContentBlock::Text(v2::TextContent::new("world")),
9962                ])
9963                .meta(meta.clone()),
9964        ))
9965        .expect("v2 -> v1 conversion");
9966        assert_eq!(
9967            chunks,
9968            vec![
9969                v1::SessionUpdate::UserMessageChunk(
9970                    v1::ContentChunk::new(v1::ContentBlock::Text(v1::TextContent::new("hello")))
9971                        .message_id("msg_user")
9972                        .meta(meta.clone())
9973                ),
9974                v1::SessionUpdate::UserMessageChunk(
9975                    v1::ContentChunk::new(v1::ContentBlock::Text(v1::TextContent::new("world")))
9976                        .message_id("msg_user")
9977                        .meta(meta)
9978                ),
9979            ]
9980        );
9981
9982        assert_eq!(
9983            v2_to_v1_many(v2::SessionUpdate::AgentMessage(
9984                v2::AgentMessage::new("msg_agent")
9985                    .content(vec![v2::ContentBlock::Text(v2::TextContent::new("hello"))])
9986            ))
9987            .expect("v2 -> v1 conversion"),
9988            vec![v1::SessionUpdate::AgentMessageChunk(
9989                v1::ContentChunk::new(v1::ContentBlock::Text(v1::TextContent::new("hello")))
9990                    .message_id("msg_agent")
9991            )]
9992        );
9993
9994        assert_eq!(
9995            v2_to_v1_many(v2::SessionUpdate::AgentThought(
9996                v2::AgentThought::new("msg_thought").content(vec![v2::ContentBlock::Text(
9997                    v2::TextContent::new("thinking")
9998                )])
9999            ))
10000            .expect("v2 -> v1 conversion"),
10001            vec![v1::SessionUpdate::AgentThoughtChunk(
10002                v1::ContentChunk::new(v1::ContentBlock::Text(v1::TextContent::new("thinking")))
10003                    .message_id("msg_thought")
10004            )]
10005        );
10006    }
10007
10008    #[test]
10009    fn v2_full_message_session_notification_fans_out_to_v1_chunk_notifications() {
10010        let notification = v2::UpdateSessionNotification::new(
10011            "sess",
10012            v2::SessionUpdate::AgentMessage(v2::AgentMessage::new("msg_agent").content(vec![
10013                v2::ContentBlock::Text(v2::TextContent::new("hello")),
10014                v2::ContentBlock::Text(v2::TextContent::new("world")),
10015            ])),
10016        );
10017
10018        let notifications = v2_to_v1_many(notification).expect("v2 -> v1 conversion");
10019        assert_eq!(
10020            notifications,
10021            vec![
10022                v1::SessionNotification::new(
10023                    "sess",
10024                    v1::SessionUpdate::AgentMessageChunk(
10025                        v1::ContentChunk::new(v1::ContentBlock::Text(v1::TextContent::new(
10026                            "hello"
10027                        )))
10028                        .message_id("msg_agent")
10029                    )
10030                ),
10031                v1::SessionNotification::new(
10032                    "sess",
10033                    v1::SessionUpdate::AgentMessageChunk(
10034                        v1::ContentChunk::new(v1::ContentBlock::Text(v1::TextContent::new(
10035                            "world"
10036                        )))
10037                        .message_id("msg_agent")
10038                    )
10039                ),
10040            ]
10041        );
10042    }
10043
10044    #[test]
10045    fn v2_json_rpc_agent_notification_fans_out_to_v1_chunk_notifications() {
10046        let message = v2::JsonRpcMessage::wrap(v2::Notification {
10047            method: "session/update".into(),
10048            params: Some(v2::AgentNotification::UpdateSessionNotification(Box::new(
10049                v2::UpdateSessionNotification::new(
10050                    "sess",
10051                    v2::SessionUpdate::AgentMessage(v2::AgentMessage::new("msg_agent").content(
10052                        vec![
10053                            v2::ContentBlock::Text(v2::TextContent::new("hello")),
10054                            v2::ContentBlock::Text(v2::TextContent::new("world")),
10055                        ],
10056                    )),
10057                ),
10058            ))),
10059        });
10060
10061        let messages = v2_to_v1_many(message).expect("v2 -> v1 conversion");
10062        let json = messages
10063            .into_iter()
10064            .map(|message| serde_json::to_value(message).expect("serialize v1 message"))
10065            .collect::<Vec<_>>();
10066        assert_eq!(
10067            json,
10068            vec![
10069                serde_json::json!({
10070                    "jsonrpc": "2.0",
10071                    "method": "session/update",
10072                    "params": {
10073                        "sessionId": "sess",
10074                        "update": {
10075                            "sessionUpdate": "agent_message_chunk",
10076                            "content": {
10077                                "type": "text",
10078                                "text": "hello"
10079                            },
10080                            "messageId": "msg_agent"
10081                        }
10082                    }
10083                }),
10084                serde_json::json!({
10085                    "jsonrpc": "2.0",
10086                    "method": "session/update",
10087                    "params": {
10088                        "sessionId": "sess",
10089                        "update": {
10090                            "sessionUpdate": "agent_message_chunk",
10091                            "content": {
10092                                "type": "text",
10093                                "text": "world"
10094                            },
10095                            "messageId": "msg_agent"
10096                        }
10097                    }
10098                }),
10099            ]
10100        );
10101    }
10102
10103    #[test]
10104    fn v2_message_patches_and_clears_do_not_convert_to_v1_chunks() {
10105        assert_v2_to_v1_many_error(
10106            v2::SessionUpdate::AgentMessage(v2::AgentMessage::new("msg_agent")),
10107            "v2 SessionUpdate variant `agent_message` without content cannot be represented in v1 chunks",
10108        );
10109
10110        assert_v2_to_v1_many_error(
10111            v2::SessionUpdate::AgentMessage(
10112                v2::AgentMessage::new("msg_agent").content(None::<Vec<v2::ContentBlock>>),
10113            ),
10114            "v2 SessionUpdate variant `agent_message` with null content cannot be represented in v1 chunks",
10115        );
10116
10117        assert_v2_to_v1_many_error(
10118            v2::SessionUpdate::AgentMessage(
10119                v2::AgentMessage::new("msg_agent").content(Vec::<v2::ContentBlock>::new()),
10120            ),
10121            "v2 SessionUpdate variant `agent_message` with empty content cannot be represented in v1 chunks",
10122        );
10123
10124        assert_v2_to_v1_many_error(
10125            v2::SessionUpdate::AgentMessage(
10126                v2::AgentMessage::new("msg_agent")
10127                    .content(vec![v2::ContentBlock::Text(v2::TextContent::new("hello"))])
10128                    .meta(None::<v2::Meta>),
10129            ),
10130            "v2 SessionUpdate variant `agent_message` with null _meta cannot be represented in v1 chunks",
10131        );
10132    }
10133
10134    #[test]
10135    fn v2_tool_call_content_chunk_does_not_convert_to_v1_replacement_update() {
10136        assert_v2_to_v1_many_error(
10137            v2::SessionUpdate::ToolCallContentChunk(v2::ToolCallContentChunk::new(
10138                "tc_1",
10139                v2::ContentBlock::Text(v2::TextContent::new("partial output")),
10140            )),
10141            "v2 SessionUpdate variant `tool_call_content_chunk` cannot be represented in v1 because v1 tool-call content updates replace content instead of appending",
10142        );
10143    }
10144
10145    #[test]
10146    fn v1_content_chunk_without_message_id_does_not_convert_to_v2() {
10147        assert_v1_to_v2_error(
10148            v1::ContentChunk::new(v1::ContentBlock::Text(v1::TextContent::new("missing"))),
10149            "v1 ContentChunk without messageId cannot be represented in v2",
10150        );
10151    }
10152
10153    #[test]
10154    fn v1_plan_session_update_converts_to_v2_item_plan_update() {
10155        let update = v1::SessionUpdate::Plan(v1::Plan::new(vec![v1::PlanEntry::new(
10156            "step",
10157            v1::PlanEntryPriority::High,
10158            v1::PlanEntryStatus::InProgress,
10159        )]));
10160
10161        let as_v2: v2::SessionUpdate = v1_to_v2(update.clone()).unwrap();
10162        assert_eq!(
10163            serde_json::to_value(&as_v2).unwrap(),
10164            serde_json::json!({
10165                "sessionUpdate": "plan_update",
10166                "plan": {
10167                    "type": "items",
10168                    "planId": LEGACY_V1_PLAN_ID,
10169                    "entries": [
10170                        {
10171                            "content": "step",
10172                            "priority": "high",
10173                            "status": "in_progress"
10174                        }
10175                    ]
10176                }
10177            })
10178        );
10179
10180        let back = v2_to_v1_many(as_v2).unwrap();
10181        #[cfg(not(feature = "unstable_plan_operations"))]
10182        assert_eq!(back, vec![update]);
10183        #[cfg(feature = "unstable_plan_operations")]
10184        assert!(matches!(
10185            back.as_slice(),
10186            [v1::SessionUpdate::PlanUpdate(_)]
10187        ));
10188    }
10189
10190    #[test]
10191    fn unknown_v2_session_update_does_not_convert_to_v1() {
10192        let update = v2::SessionUpdate::Other(v2::OtherSessionUpdate::new(
10193            "_status_badge",
10194            std::collections::BTreeMap::new(),
10195        ));
10196
10197        assert_v2_to_v1_many_error(
10198            update,
10199            "v2 SessionUpdate variant `_status_badge` cannot be represented in v1",
10200        );
10201    }
10202
10203    #[test]
10204    fn v2_state_update_does_not_convert_to_v1() {
10205        assert_v2_to_v1_many_error(
10206            v2::SessionUpdate::StateUpdate(v2::StateUpdate::Idle(
10207                v2::IdleStateUpdate::new().stop_reason(v2::StopReason::EndTurn),
10208            )),
10209            "v2 SessionUpdate variant `state_update` cannot be represented in v1 because v1 reports completion in the session/prompt response",
10210        );
10211    }
10212
10213    #[test]
10214    fn v1_current_mode_update_does_not_convert_to_v2() {
10215        assert_v1_to_v2_error(
10216            v1::SessionUpdate::CurrentModeUpdate(v1::CurrentModeUpdate::new("ask")),
10217            "v1 SessionUpdate variant `current_mode_update` cannot be represented in v2",
10218        );
10219    }
10220
10221    #[test]
10222    fn v1_session_mode_methods_do_not_convert_to_v2() {
10223        assert_v1_to_v2_error(
10224            v1::ClientRequest::SetSessionModeRequest(v1::SetSessionModeRequest::new("sess", "ask")),
10225            "v1 ClientRequest variant `session/set_mode` cannot be represented in v2",
10226        );
10227        assert_v1_to_v2_error(
10228            v1::AgentResponse::SetSessionModeResponse(v1::SetSessionModeResponse::new()),
10229            "v1 AgentResponse variant `session/set_mode` cannot be represented in v2",
10230        );
10231    }
10232
10233    #[test]
10234    fn v1_session_response_modes_fall_back_to_none_in_v2() {
10235        let response = v1::NewSessionResponse::new("sess").modes(v1::SessionModeState::new(
10236            "ask",
10237            vec![v1::SessionMode::new("ask", "Ask")],
10238        ));
10239
10240        let as_v2: v2::NewSessionResponse = v1_to_v2(response).unwrap();
10241        let back_to_v1: v1::NewSessionResponse = v2_to_v1(as_v2).unwrap();
10242
10243        assert!(back_to_v1.modes.is_none());
10244    }
10245
10246    #[test]
10247    fn v1_session_response_missing_config_options_becomes_empty_v2_vec() {
10248        let new_response: v2::NewSessionResponse =
10249            v1_to_v2(v1::NewSessionResponse::new("sess")).unwrap();
10250        assert!(new_response.config_options.is_empty());
10251
10252        let load_response: v2::ResumeSessionResponse =
10253            v1_to_v2(v1::LoadSessionResponse::new()).unwrap();
10254        assert!(load_response.config_options.is_empty());
10255
10256        let resume_response: v2::ResumeSessionResponse =
10257            v1_to_v2(v1::ResumeSessionResponse::new()).unwrap();
10258        assert!(resume_response.config_options.is_empty());
10259
10260        #[cfg(feature = "unstable_session_fork")]
10261        {
10262            let fork_response: v2::ForkSessionResponse =
10263                v1_to_v2(v1::ForkSessionResponse::new("fork")).unwrap();
10264            assert!(fork_response.config_options.is_empty());
10265        }
10266    }
10267
10268    #[test]
10269    fn v2_resume_replay_from_start_maps_to_v1_load_request() {
10270        let v1_load = v1::ClientRequest::LoadSessionRequest(v1::LoadSessionRequest::new(
10271            "sess",
10272            "/workspace/project",
10273        ));
10274        let v2_request: v2::ClientRequest = v1_to_v2(v1_load).unwrap();
10275        let v2::ClientRequest::ResumeSessionRequest(resume) = v2_request else {
10276            panic!("v1 session/load should convert to v2 session/resume");
10277        };
10278        assert!(matches!(resume.replay_from, Some(v2::ReplayFrom::Start(_))));
10279
10280        let v1_request: v1::ClientRequest =
10281            v2_to_v1(v2::ClientRequest::ResumeSessionRequest(resume)).unwrap();
10282        assert!(matches!(
10283            v1_request,
10284            v1::ClientRequest::LoadSessionRequest(_)
10285        ));
10286    }
10287
10288    #[test]
10289    fn v2_resume_without_replay_maps_to_v1_resume_request() {
10290        let v2_request = v2::ClientRequest::ResumeSessionRequest(Box::new(
10291            v2::ResumeSessionRequest::new("sess", "/workspace/project"),
10292        ));
10293
10294        let v1_request: v1::ClientRequest = v2_to_v1(v2_request).unwrap();
10295        assert!(matches!(
10296            v1_request,
10297            v1::ClientRequest::ResumeSessionRequest(_)
10298        ));
10299    }
10300
10301    #[test]
10302    fn v2_session_response_converts_to_v1_without_mode_state() {
10303        let response: v1::NewSessionResponse =
10304            v2_to_v1(v2::NewSessionResponse::new("sess")).unwrap();
10305
10306        assert!(response.modes.is_none());
10307        assert!(matches!(
10308            response.config_options,
10309            Some(config_options) if config_options.is_empty()
10310        ));
10311    }
10312
10313    #[test]
10314    fn v2_tool_call_update_conversion_matches_v1_default_on_error_fields() {
10315        let update = v2::ToolCallUpdate::new("tc")
10316            .kind(v2::ToolKind::Unknown("_future_kind".to_string()))
10317            .status(v2::ToolCallStatus::Other("_paused".to_string()))
10318            .content(vec![
10319                v2::ToolCallContent::Other(v2::OtherToolCallContent::new(
10320                    "_chart",
10321                    BTreeMap::default(),
10322                )),
10323                v2::ToolCallContent::Diff(v2::Diff::patch(
10324                    "diff --git /tmp/file.txt /tmp/file.txt\n",
10325                    vec![v2::DiffChange::modify("/tmp/file.txt")],
10326                )),
10327            ]);
10328
10329        let converted: v1::ToolCallUpdate = v2_to_v1(update).unwrap();
10330
10331        assert_eq!(converted.fields.kind, None);
10332        assert_eq!(converted.fields.status, None);
10333        assert_eq!(converted.fields.content, Some(vec![]));
10334    }
10335
10336    #[test]
10337    fn v2_collection_conversion_skips_items_like_v1_vec_skip_error() {
10338        let response = v2::InitializeResponse::new(
10339            ProtocolVersion::V2,
10340            v2::Implementation::new("test-agent", "2.0.0"),
10341        )
10342        .capabilities(v2::AgentCapabilities::new().session(v2::SessionCapabilities::new()))
10343        .auth_methods(vec![
10344            v2::AuthMethod::Other(v2::OtherAuthMethod::new(
10345                "_oauth",
10346                "oauth",
10347                "OAuth",
10348                BTreeMap::default(),
10349            )),
10350            v2::AuthMethod::Agent(v2::AuthMethodAgent::new("agent", "Agent")),
10351        ]);
10352        let converted: v1::InitializeResponse = v2_to_v1(response).unwrap();
10353        assert_eq!(converted.auth_methods.len(), 1);
10354        assert!(matches!(
10355            converted.auth_methods[0],
10356            v1::AuthMethod::Agent(_)
10357        ));
10358
10359        let config_update = v2::ConfigOptionUpdate::new(vec![
10360            v2::SessionConfigOption::select(
10361                "mode",
10362                "Mode",
10363                "ask",
10364                vec![v2::SessionConfigSelectOption::new("ask", "Ask")],
10365            ),
10366            v2::SessionConfigOption::new(
10367                "future",
10368                "Future",
10369                v2::SessionConfigKind::Other(v2::OtherSessionConfigKind::new(
10370                    "_slider",
10371                    BTreeMap::default(),
10372                )),
10373            ),
10374        ]);
10375        let converted: v1::ConfigOptionUpdate = v2_to_v1(config_update).unwrap();
10376        assert_eq!(converted.config_options.len(), 1);
10377        assert_eq!(converted.config_options[0].id.0.as_ref(), "mode");
10378    }
10379
10380    #[test]
10381    fn v2_default_on_error_fields_drop_unrepresentable_nested_values() {
10382        let command = v2::AvailableCommand::new("review", "Review changes").input(
10383            v2::AvailableCommandInput::Other(v2::OtherAvailableCommandInput::new(
10384                "_choices",
10385                BTreeMap::default(),
10386            )),
10387        );
10388        let converted: v1::AvailableCommandsUpdate =
10389            v2_to_v1(v2::AvailableCommandsUpdate::new(vec![command])).unwrap();
10390
10391        assert_eq!(converted.available_commands.len(), 1);
10392        assert_eq!(converted.available_commands[0].input, None);
10393
10394        let content = v2::TextContent::new("hello").annotations(
10395            v2::Annotations::new()
10396                .audience(vec![v2::Role::Other("_critic".to_string()), v2::Role::User]),
10397        );
10398        let converted: v1::TextContent = v2_to_v1(content).unwrap();
10399
10400        assert_eq!(
10401            converted
10402                .annotations
10403                .and_then(|annotations| annotations.audience),
10404            Some(vec![v1::Role::User])
10405        );
10406    }
10407
10408    #[test]
10409    fn available_command_input_conversion_adds_v2_discriminator() {
10410        let input = v1::AvailableCommandInput::Unstructured(v1::UnstructuredCommandInput::new(
10411            "Describe changes",
10412        ));
10413
10414        let v2_input: v2::AvailableCommandInput = v1_to_v2(input.clone()).unwrap();
10415        assert_eq!(
10416            serde_json::to_value(&v2_input).unwrap(),
10417            serde_json::json!({
10418                "type": "text",
10419                "hint": "Describe changes"
10420            })
10421        );
10422
10423        let v1_input: v1::AvailableCommandInput = v2_to_v1(v2_input).unwrap();
10424        assert_eq!(v1_input, input);
10425        assert_eq!(
10426            serde_json::to_value(v1_input).unwrap(),
10427            serde_json::json!({
10428                "hint": "Describe changes"
10429            })
10430        );
10431    }
10432
10433    #[test]
10434    fn v2_plan_entries_skip_unrepresentable_items_inside_tolerant_vectors() {
10435        let update = v2::PlanUpdate::new(v2::PlanUpdateContent::items(
10436            "main",
10437            vec![
10438                v2::PlanEntry::new(
10439                    "keep",
10440                    v2::PlanEntryPriority::High,
10441                    v2::PlanEntryStatus::Pending,
10442                ),
10443                v2::PlanEntry::new(
10444                    "drop",
10445                    v2::PlanEntryPriority::Other("_critical".to_string()),
10446                    v2::PlanEntryStatus::Pending,
10447                ),
10448            ],
10449        ));
10450
10451        #[cfg(not(feature = "unstable_plan_operations"))]
10452        {
10453            let converted: v1::Plan = v2_to_v1(update).unwrap();
10454            assert_eq!(converted.entries.len(), 1);
10455            assert_eq!(converted.entries[0].content, "keep");
10456        }
10457
10458        #[cfg(feature = "unstable_plan_operations")]
10459        {
10460            let converted: v1::PlanUpdate = v2_to_v1(update).unwrap();
10461            let v1::PlanUpdateContent::Items(items) = converted.plan else {
10462                panic!("expected item plan update");
10463            };
10464            assert_eq!(items.entries.len(), 1);
10465            assert_eq!(items.entries[0].content, "keep");
10466        }
10467    }
10468
10469    #[test]
10470    fn v1_tool_call_update_conversion_skips_items_for_v2_vec_skip_error_fields() {
10471        let update = v1::ToolCallUpdate::new(
10472            "tc",
10473            v1::ToolCallUpdateFields::new().content(vec![
10474                v1::ToolCallContent::Terminal(v1::Terminal::new("term")),
10475                v1::ToolCallContent::Diff(v1::Diff::new("/tmp/file.txt", "new")),
10476            ]),
10477        );
10478
10479        let converted: v2::ToolCallUpdate = v1_to_v2(update).unwrap();
10480        assert_eq!(
10481            converted.content,
10482            crate::MaybeUndefined::Value(vec![v2::ToolCallContent::Diff(v2::Diff::patch(
10483                full_file_git_patch(&PathBuf::from("/tmp/file.txt"), None, "new"),
10484                vec![v2::DiffChange::add("/tmp/file.txt").file_type(v2::DiffFileType::Text)],
10485            ))])
10486        );
10487    }
10488
10489    #[test]
10490    fn v2_resource_link_icons_do_not_convert_to_v1() {
10491        assert_v2_to_v1_error(
10492            v2::ResourceLink::new("file.txt", "file:///file.txt")
10493                .icons(vec![v2::Icon::new("https://example.com/icon.png")]),
10494            "v2 ResourceLink.icons cannot be represented in v1",
10495        );
10496    }
10497
10498    #[test]
10499    fn unknown_v2_raw_fallbacks_do_not_convert_to_v1() {
10500        assert_v2_to_v1_error(
10501            v2::ContentBlock::Other(v2::OtherContentBlock::new(
10502                "_widget",
10503                std::collections::BTreeMap::new(),
10504            )),
10505            "v2 ContentBlock variant `_widget` cannot be represented in v1",
10506        );
10507        assert_v2_to_v1_error(
10508            v2::ToolCallContent::Other(v2::OtherToolCallContent::new(
10509                "_chart",
10510                std::collections::BTreeMap::new(),
10511            )),
10512            "v2 ToolCallContent variant `_chart` cannot be represented in v1",
10513        );
10514        assert_v2_to_v1_error(
10515            v2::AvailableCommandInput::Other(v2::OtherAvailableCommandInput::new(
10516                "_choices",
10517                std::collections::BTreeMap::new(),
10518            )),
10519            "v2 AvailableCommandInput variant `_choices` cannot be represented in v1",
10520        );
10521        assert_v2_to_v1_error(
10522            v2::RequestPermissionRequest::new("session-id", "Permission requested", Vec::new())
10523                .subject(v2::RequestPermissionSubject::Other(
10524                    v2::OtherRequestPermissionSubject::new(
10525                        "_review",
10526                        std::collections::BTreeMap::new(),
10527                    ),
10528                )),
10529            "v2 RequestPermissionSubject variant `_review` cannot be represented in v1",
10530        );
10531        assert_v2_to_v1_error(
10532            v2::RequestPermissionRequest::new("session-id", "Permission requested", Vec::new()),
10533            "v2 RequestPermissionRequest without `subject` cannot be represented in v1",
10534        );
10535        assert_v2_to_v1_error(
10536            v2::RequestPermissionOutcome::Other(v2::OtherRequestPermissionOutcome::new(
10537                "_defer",
10538                std::collections::BTreeMap::new(),
10539            )),
10540            "v2 RequestPermissionOutcome variant `_defer` cannot be represented in v1",
10541        );
10542        assert_v2_to_v1_error(
10543            v2::SessionConfigKind::Other(v2::OtherSessionConfigKind::new(
10544                "_slider",
10545                std::collections::BTreeMap::new(),
10546            )),
10547            "v2 SessionConfigKind variant `_slider` cannot be represented in v1",
10548        );
10549        assert_v2_to_v1_error(
10550            v2::AuthMethod::Other(v2::OtherAuthMethod::new(
10551                "_oauth",
10552                "oauth",
10553                "OAuth",
10554                std::collections::BTreeMap::new(),
10555            )),
10556            "v2 AuthMethod variant `_oauth` cannot be represented in v1",
10557        );
10558        assert_v2_to_v1_error(
10559            v2::PlanUpdate::new(v2::PlanUpdateContent::Other(
10560                v2::OtherPlanUpdateContent::new(
10561                    "_timeline",
10562                    "plan-1",
10563                    std::collections::BTreeMap::new(),
10564                ),
10565            )),
10566            "v2 PlanUpdateContent variant `_timeline` cannot be represented in v1",
10567        );
10568        #[cfg(feature = "unstable_nes")]
10569        assert_v2_to_v1_error(
10570            v2::NesSuggestion::Other(v2::OtherNesSuggestion::new(
10571                "_preview",
10572                "preview-1",
10573                std::collections::BTreeMap::new(),
10574            )),
10575            "v2 NesSuggestion variant `_preview` cannot be represented in v1",
10576        );
10577    }
10578
10579    #[test]
10580    fn round_trips_request_permission_outcomes() {
10581        let cancelled = v1::RequestPermissionResponse::new(v1::RequestPermissionOutcome::Cancelled);
10582        assert_v1_round_trip::<v1::RequestPermissionResponse, v2::RequestPermissionResponse>(
10583            cancelled,
10584        );
10585
10586        let selected = v1::RequestPermissionResponse::new(v1::RequestPermissionOutcome::Selected(
10587            v1::SelectedPermissionOutcome::new("opt_1"),
10588        ));
10589        assert_v1_round_trip::<v1::RequestPermissionResponse, v2::RequestPermissionResponse>(
10590            selected,
10591        );
10592    }
10593
10594    #[test]
10595    fn converts_v1_request_permission_request_with_required_v2_title() {
10596        let titled = v1::RequestPermissionRequest::new(
10597            "session-id",
10598            v1::ToolCallUpdate::new("call_1", v1::ToolCallUpdateFields::new().title("Read file")),
10599            Vec::new(),
10600        );
10601
10602        let converted: v2::RequestPermissionRequest = v1_to_v2(titled).unwrap();
10603        assert_eq!(converted.title, "Read file");
10604        let Some(v2::RequestPermissionSubject::ToolCall(subject)) = converted.subject else {
10605            panic!("expected tool-call permission subject");
10606        };
10607        assert_eq!(subject.tool_call.tool_call_id.to_string(), "call_1");
10608
10609        let fallback = v1::RequestPermissionRequest::new(
10610            "session-id",
10611            v1::ToolCallUpdate::new("call_2", v1::ToolCallUpdateFields::new()),
10612            Vec::new(),
10613        );
10614
10615        let converted: v2::RequestPermissionRequest = v1_to_v2(fallback).unwrap();
10616        assert_eq!(converted.title, "Permission requested");
10617        let Some(v2::RequestPermissionSubject::ToolCall(subject)) = converted.subject else {
10618            panic!("expected tool-call permission subject");
10619        };
10620        assert_eq!(subject.tool_call.tool_call_id.to_string(), "call_2");
10621    }
10622
10623    #[test]
10624    fn round_trips_error_with_data_payload() {
10625        let err = v1::Error::invalid_params().data(serde_json::json!({
10626            "reason": "missing field",
10627            "field": "sessionId",
10628        }));
10629        assert_v1_round_trip::<v1::Error, v2::Error>(err);
10630    }
10631
10632    #[test]
10633    fn round_trips_v2_value_back_through_v1() {
10634        // Same coverage but starting from v2, to exercise IntoV1 explicitly.
10635        let request = v2::PromptRequest::new(
10636            "sess_2",
10637            vec![v2::ContentBlock::Text(v2::TextContent::new("hi"))],
10638        );
10639        assert_v2_round_trip::<v2::PromptRequest, v1::PromptRequest>(request.clone());
10640        assert_json_eq_after_v2_to_v1::<v2::PromptRequest, v1::PromptRequest>(request);
10641    }
10642
10643    #[test]
10644    fn protocol_version_constants_remain_explicit() {
10645        assert_eq!(ProtocolVersion::V1.as_u16(), 1);
10646        assert_eq!(ProtocolVersion::V2.as_u16(), 2);
10647    }
10648
10649    /// `?` bubbles a [`ProtocolConversionError`] into a [`v1::Error`] without
10650    /// loss of message, mapped onto the internal-error code.
10651    #[test]
10652    fn protocol_conversion_error_maps_into_v1_error() {
10653        fn run() -> std::result::Result<(), v1::Error> {
10654            // Synthesize a conversion error so we don't have to wait for v2
10655            // to actually diverge before exercising the `?` path.
10656            Err(ProtocolConversionError::new("missing required field"))?;
10657            unreachable!();
10658        }
10659
10660        let err = run().unwrap_err();
10661        assert_eq!(err.code, v1::ErrorCode::InternalError);
10662        assert_eq!(
10663            err.data,
10664            Some(serde_json::Value::String(
10665                "missing required field".to_string()
10666            ))
10667        );
10668    }
10669
10670    /// Mirror of the v1 test for the v2 [`Error`] type.
10671    #[test]
10672    fn protocol_conversion_error_maps_into_v2_error() {
10673        fn run() -> std::result::Result<(), v2::Error> {
10674            Err(ProtocolConversionError::new("missing required field"))?;
10675            unreachable!();
10676        }
10677
10678        let err = run().unwrap_err();
10679        assert_eq!(err.code, v2::ErrorCode::InternalError);
10680        assert_eq!(
10681            err.data,
10682            Some(serde_json::Value::String(
10683                "missing required field".to_string()
10684            ))
10685        );
10686    }
10687}