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 { value, title, meta } = self;
7620        Ok(crate::v1::EnumOption {
7621            value: value.into_v1()?,
7622            title: title.into_v1()?,
7623            meta: meta.into_v1()?,
7624        })
7625    }
7626}
7627
7628#[cfg(feature = "unstable_elicitation")]
7629impl IntoV2 for crate::v1::EnumOption {
7630    type Output = super::EnumOption;
7631
7632    fn into_v2(self) -> Result<Self::Output> {
7633        let Self { value, title, meta } = self;
7634        Ok(super::EnumOption {
7635            value: value.into_v2()?,
7636            title: title.into_v2()?,
7637            meta: meta.into_v2()?,
7638        })
7639    }
7640}
7641
7642#[cfg(feature = "unstable_elicitation")]
7643impl IntoV1 for super::StringPropertySchema {
7644    type Output = crate::v1::StringPropertySchema;
7645
7646    fn into_v1(self) -> Result<Self::Output> {
7647        let Self {
7648            title,
7649            description,
7650            min_length,
7651            max_length,
7652            pattern,
7653            format,
7654            default,
7655            enum_values,
7656            one_of,
7657            meta,
7658        } = self;
7659        Ok(crate::v1::StringPropertySchema {
7660            title: title.into_v1()?,
7661            description: description.into_v1()?,
7662            min_length: min_length.into_v1()?,
7663            max_length: max_length.into_v1()?,
7664            pattern: pattern.into_v1()?,
7665            format: format.into_v1()?,
7666            default: default.into_v1()?,
7667            enum_values: enum_values.into_v1()?,
7668            one_of: one_of.into_v1()?,
7669            meta: meta.into_v1()?,
7670        })
7671    }
7672}
7673
7674#[cfg(feature = "unstable_elicitation")]
7675impl IntoV2 for crate::v1::StringPropertySchema {
7676    type Output = super::StringPropertySchema;
7677
7678    fn into_v2(self) -> Result<Self::Output> {
7679        let Self {
7680            title,
7681            description,
7682            min_length,
7683            max_length,
7684            pattern,
7685            format,
7686            default,
7687            enum_values,
7688            one_of,
7689            meta,
7690        } = self;
7691        Ok(super::StringPropertySchema {
7692            title: title.into_v2()?,
7693            description: description.into_v2()?,
7694            min_length: min_length.into_v2()?,
7695            max_length: max_length.into_v2()?,
7696            pattern: pattern.into_v2()?,
7697            format: format.into_v2()?,
7698            default: default.into_v2()?,
7699            enum_values: enum_values.into_v2()?,
7700            one_of: one_of.into_v2()?,
7701            meta: meta.into_v2()?,
7702        })
7703    }
7704}
7705
7706#[cfg(feature = "unstable_elicitation")]
7707impl IntoV1 for super::NumberPropertySchema {
7708    type Output = crate::v1::NumberPropertySchema;
7709
7710    fn into_v1(self) -> Result<Self::Output> {
7711        let Self {
7712            title,
7713            description,
7714            minimum,
7715            maximum,
7716            default,
7717            meta,
7718        } = self;
7719        Ok(crate::v1::NumberPropertySchema {
7720            title: title.into_v1()?,
7721            description: description.into_v1()?,
7722            minimum: minimum.into_v1()?,
7723            maximum: maximum.into_v1()?,
7724            default: default.into_v1()?,
7725            meta: meta.into_v1()?,
7726        })
7727    }
7728}
7729
7730#[cfg(feature = "unstable_elicitation")]
7731impl IntoV2 for crate::v1::NumberPropertySchema {
7732    type Output = super::NumberPropertySchema;
7733
7734    fn into_v2(self) -> Result<Self::Output> {
7735        let Self {
7736            title,
7737            description,
7738            minimum,
7739            maximum,
7740            default,
7741            meta,
7742        } = self;
7743        Ok(super::NumberPropertySchema {
7744            title: title.into_v2()?,
7745            description: description.into_v2()?,
7746            minimum: minimum.into_v2()?,
7747            maximum: maximum.into_v2()?,
7748            default: default.into_v2()?,
7749            meta: meta.into_v2()?,
7750        })
7751    }
7752}
7753
7754#[cfg(feature = "unstable_elicitation")]
7755impl IntoV1 for super::IntegerPropertySchema {
7756    type Output = crate::v1::IntegerPropertySchema;
7757
7758    fn into_v1(self) -> Result<Self::Output> {
7759        let Self {
7760            title,
7761            description,
7762            minimum,
7763            maximum,
7764            default,
7765            meta,
7766        } = self;
7767        Ok(crate::v1::IntegerPropertySchema {
7768            title: title.into_v1()?,
7769            description: description.into_v1()?,
7770            minimum: minimum.into_v1()?,
7771            maximum: maximum.into_v1()?,
7772            default: default.into_v1()?,
7773            meta: meta.into_v1()?,
7774        })
7775    }
7776}
7777
7778#[cfg(feature = "unstable_elicitation")]
7779impl IntoV2 for crate::v1::IntegerPropertySchema {
7780    type Output = super::IntegerPropertySchema;
7781
7782    fn into_v2(self) -> Result<Self::Output> {
7783        let Self {
7784            title,
7785            description,
7786            minimum,
7787            maximum,
7788            default,
7789            meta,
7790        } = self;
7791        Ok(super::IntegerPropertySchema {
7792            title: title.into_v2()?,
7793            description: description.into_v2()?,
7794            minimum: minimum.into_v2()?,
7795            maximum: maximum.into_v2()?,
7796            default: default.into_v2()?,
7797            meta: meta.into_v2()?,
7798        })
7799    }
7800}
7801
7802#[cfg(feature = "unstable_elicitation")]
7803impl IntoV1 for super::BooleanPropertySchema {
7804    type Output = crate::v1::BooleanPropertySchema;
7805
7806    fn into_v1(self) -> Result<Self::Output> {
7807        let Self {
7808            title,
7809            description,
7810            default,
7811            meta,
7812        } = self;
7813        Ok(crate::v1::BooleanPropertySchema {
7814            title: title.into_v1()?,
7815            description: description.into_v1()?,
7816            default: default.into_v1()?,
7817            meta: meta.into_v1()?,
7818        })
7819    }
7820}
7821
7822#[cfg(feature = "unstable_elicitation")]
7823impl IntoV2 for crate::v1::BooleanPropertySchema {
7824    type Output = super::BooleanPropertySchema;
7825
7826    fn into_v2(self) -> Result<Self::Output> {
7827        let Self {
7828            title,
7829            description,
7830            default,
7831            meta,
7832        } = self;
7833        Ok(super::BooleanPropertySchema {
7834            title: title.into_v2()?,
7835            description: description.into_v2()?,
7836            default: default.into_v2()?,
7837            meta: meta.into_v2()?,
7838        })
7839    }
7840}
7841
7842#[cfg(feature = "unstable_elicitation")]
7843impl IntoV1 for super::StringMultiSelectItems {
7844    type Output = crate::v1::StringMultiSelectItems;
7845
7846    fn into_v1(self) -> Result<Self::Output> {
7847        let Self { values, meta } = self;
7848        Ok(crate::v1::StringMultiSelectItems {
7849            values: values.into_v1()?,
7850            meta: meta.into_v1()?,
7851        })
7852    }
7853}
7854
7855#[cfg(feature = "unstable_elicitation")]
7856impl IntoV2 for crate::v1::StringMultiSelectItems {
7857    type Output = super::StringMultiSelectItems;
7858
7859    fn into_v2(self) -> Result<Self::Output> {
7860        let Self { values, meta } = self;
7861        Ok(super::StringMultiSelectItems {
7862            values: values.into_v2()?,
7863            meta: meta.into_v2()?,
7864        })
7865    }
7866}
7867
7868#[cfg(feature = "unstable_elicitation")]
7869impl IntoV1 for super::OtherMultiSelectItems {
7870    type Output = crate::v1::OtherMultiSelectItems;
7871
7872    fn into_v1(self) -> Result<Self::Output> {
7873        let Self { type_, fields } = self;
7874        Ok(crate::v1::OtherMultiSelectItems {
7875            type_: type_.into_v1()?,
7876            fields: fields.into_v1()?,
7877        })
7878    }
7879}
7880
7881#[cfg(feature = "unstable_elicitation")]
7882impl IntoV2 for crate::v1::OtherMultiSelectItems {
7883    type Output = super::OtherMultiSelectItems;
7884
7885    fn into_v2(self) -> Result<Self::Output> {
7886        let Self { type_, fields } = self;
7887        Ok(super::OtherMultiSelectItems {
7888            type_: type_.into_v2()?,
7889            fields: fields.into_v2()?,
7890        })
7891    }
7892}
7893
7894#[cfg(feature = "unstable_elicitation")]
7895impl IntoV1 for super::TitledMultiSelectItems {
7896    type Output = crate::v1::TitledMultiSelectItems;
7897
7898    fn into_v1(self) -> Result<Self::Output> {
7899        let Self { options, meta } = self;
7900        Ok(crate::v1::TitledMultiSelectItems {
7901            options: options.into_v1()?,
7902            meta: meta.into_v1()?,
7903        })
7904    }
7905}
7906
7907#[cfg(feature = "unstable_elicitation")]
7908impl IntoV2 for crate::v1::TitledMultiSelectItems {
7909    type Output = super::TitledMultiSelectItems;
7910
7911    fn into_v2(self) -> Result<Self::Output> {
7912        let Self { options, meta } = self;
7913        Ok(super::TitledMultiSelectItems {
7914            options: options.into_v2()?,
7915            meta: meta.into_v2()?,
7916        })
7917    }
7918}
7919
7920#[cfg(feature = "unstable_elicitation")]
7921impl IntoV1 for super::MultiSelectItems {
7922    type Output = crate::v1::MultiSelectItems;
7923
7924    fn into_v1(self) -> Result<Self::Output> {
7925        Ok(match self {
7926            Self::String(value) => crate::v1::MultiSelectItems::String(value.into_v1()?),
7927            Self::Other(value) => crate::v1::MultiSelectItems::Other(value.into_v1()?),
7928            Self::Titled(value) => crate::v1::MultiSelectItems::Titled(value.into_v1()?),
7929        })
7930    }
7931}
7932
7933#[cfg(feature = "unstable_elicitation")]
7934impl IntoV2 for crate::v1::MultiSelectItems {
7935    type Output = super::MultiSelectItems;
7936
7937    fn into_v2(self) -> Result<Self::Output> {
7938        Ok(match self {
7939            Self::String(value) => super::MultiSelectItems::String(value.into_v2()?),
7940            Self::Other(value) => super::MultiSelectItems::Other(value.into_v2()?),
7941            Self::Titled(value) => super::MultiSelectItems::Titled(value.into_v2()?),
7942        })
7943    }
7944}
7945
7946#[cfg(feature = "unstable_elicitation")]
7947impl IntoV1 for super::MultiSelectPropertySchema {
7948    type Output = crate::v1::MultiSelectPropertySchema;
7949
7950    fn into_v1(self) -> Result<Self::Output> {
7951        let Self {
7952            title,
7953            description,
7954            min_items,
7955            max_items,
7956            items,
7957            default,
7958            meta,
7959        } = self;
7960        Ok(crate::v1::MultiSelectPropertySchema {
7961            title: title.into_v1()?,
7962            description: description.into_v1()?,
7963            min_items: min_items.into_v1()?,
7964            max_items: max_items.into_v1()?,
7965            items: items.into_v1()?,
7966            default: default.into_v1()?,
7967            meta: meta.into_v1()?,
7968        })
7969    }
7970}
7971
7972#[cfg(feature = "unstable_elicitation")]
7973impl IntoV2 for crate::v1::MultiSelectPropertySchema {
7974    type Output = super::MultiSelectPropertySchema;
7975
7976    fn into_v2(self) -> Result<Self::Output> {
7977        let Self {
7978            title,
7979            description,
7980            min_items,
7981            max_items,
7982            items,
7983            default,
7984            meta,
7985        } = self;
7986        Ok(super::MultiSelectPropertySchema {
7987            title: title.into_v2()?,
7988            description: description.into_v2()?,
7989            min_items: min_items.into_v2()?,
7990            max_items: max_items.into_v2()?,
7991            items: items.into_v2()?,
7992            default: default.into_v2()?,
7993            meta: meta.into_v2()?,
7994        })
7995    }
7996}
7997
7998#[cfg(feature = "unstable_elicitation")]
7999impl IntoV1 for super::ElicitationPropertySchema {
8000    type Output = crate::v1::ElicitationPropertySchema;
8001
8002    fn into_v1(self) -> Result<Self::Output> {
8003        Ok(match self {
8004            Self::String(value) => crate::v1::ElicitationPropertySchema::String(value.into_v1()?),
8005            Self::Number(value) => crate::v1::ElicitationPropertySchema::Number(value.into_v1()?),
8006            Self::Integer(value) => crate::v1::ElicitationPropertySchema::Integer(value.into_v1()?),
8007            Self::Boolean(value) => crate::v1::ElicitationPropertySchema::Boolean(value.into_v1()?),
8008            Self::Array(value) => crate::v1::ElicitationPropertySchema::Array(value.into_v1()?),
8009            Self::Other(value) => crate::v1::ElicitationPropertySchema::Other(value.into_v1()?),
8010        })
8011    }
8012}
8013
8014#[cfg(feature = "unstable_elicitation")]
8015impl IntoV2 for crate::v1::ElicitationPropertySchema {
8016    type Output = super::ElicitationPropertySchema;
8017
8018    fn into_v2(self) -> Result<Self::Output> {
8019        Ok(match self {
8020            Self::String(value) => super::ElicitationPropertySchema::String(value.into_v2()?),
8021            Self::Number(value) => super::ElicitationPropertySchema::Number(value.into_v2()?),
8022            Self::Integer(value) => super::ElicitationPropertySchema::Integer(value.into_v2()?),
8023            Self::Boolean(value) => super::ElicitationPropertySchema::Boolean(value.into_v2()?),
8024            Self::Array(value) => super::ElicitationPropertySchema::Array(value.into_v2()?),
8025            Self::Other(value) => super::ElicitationPropertySchema::Other(value.into_v2()?),
8026        })
8027    }
8028}
8029
8030#[cfg(feature = "unstable_elicitation")]
8031impl IntoV1 for super::OtherElicitationPropertySchema {
8032    type Output = crate::v1::OtherElicitationPropertySchema;
8033
8034    fn into_v1(self) -> Result<Self::Output> {
8035        let Self { type_, fields } = self;
8036        Ok(crate::v1::OtherElicitationPropertySchema {
8037            type_: type_.into_v1()?,
8038            fields: fields.into_v1()?,
8039        })
8040    }
8041}
8042
8043#[cfg(feature = "unstable_elicitation")]
8044impl IntoV2 for crate::v1::OtherElicitationPropertySchema {
8045    type Output = super::OtherElicitationPropertySchema;
8046
8047    fn into_v2(self) -> Result<Self::Output> {
8048        let Self { type_, fields } = self;
8049        Ok(super::OtherElicitationPropertySchema {
8050            type_: type_.into_v2()?,
8051            fields: fields.into_v2()?,
8052        })
8053    }
8054}
8055
8056#[cfg(feature = "unstable_elicitation")]
8057impl IntoV1 for super::ElicitationSchema {
8058    type Output = crate::v1::ElicitationSchema;
8059
8060    fn into_v1(self) -> Result<Self::Output> {
8061        let Self {
8062            type_,
8063            title,
8064            properties,
8065            required,
8066            description,
8067            meta,
8068        } = self;
8069        Ok(crate::v1::ElicitationSchema {
8070            type_: type_.into_v1()?,
8071            title: title.into_v1()?,
8072            properties: properties.into_v1()?,
8073            required: required.into_v1()?,
8074            description: description.into_v1()?,
8075            meta: meta.into_v1()?,
8076        })
8077    }
8078}
8079
8080#[cfg(feature = "unstable_elicitation")]
8081impl IntoV2 for crate::v1::ElicitationSchema {
8082    type Output = super::ElicitationSchema;
8083
8084    fn into_v2(self) -> Result<Self::Output> {
8085        let Self {
8086            type_,
8087            title,
8088            properties,
8089            required,
8090            description,
8091            meta,
8092        } = self;
8093        Ok(super::ElicitationSchema {
8094            type_: type_.into_v2()?,
8095            title: title.into_v2()?,
8096            properties: properties.into_v2()?,
8097            required: required.into_v2()?,
8098            description: description.into_v2()?,
8099            meta: meta.into_v2()?,
8100        })
8101    }
8102}
8103
8104#[cfg(feature = "unstable_elicitation")]
8105impl IntoV1 for super::ElicitationCapabilities {
8106    type Output = crate::v1::ElicitationCapabilities;
8107
8108    fn into_v1(self) -> Result<Self::Output> {
8109        let Self { form, url, meta } = self;
8110        Ok(crate::v1::ElicitationCapabilities {
8111            form: into_v1_default_on_error(form),
8112            url: into_v1_default_on_error(url),
8113            meta: meta.into_v1()?,
8114        })
8115    }
8116}
8117
8118#[cfg(feature = "unstable_elicitation")]
8119impl IntoV2 for crate::v1::ElicitationCapabilities {
8120    type Output = super::ElicitationCapabilities;
8121
8122    fn into_v2(self) -> Result<Self::Output> {
8123        let Self { form, url, meta } = self;
8124        Ok(super::ElicitationCapabilities {
8125            form: into_v2_default_on_error(form),
8126            url: into_v2_default_on_error(url),
8127            meta: meta.into_v2()?,
8128        })
8129    }
8130}
8131
8132#[cfg(feature = "unstable_elicitation")]
8133impl IntoV1 for super::ElicitationFormCapabilities {
8134    type Output = crate::v1::ElicitationFormCapabilities;
8135
8136    fn into_v1(self) -> Result<Self::Output> {
8137        let Self { meta } = self;
8138        Ok(crate::v1::ElicitationFormCapabilities {
8139            meta: meta.into_v1()?,
8140        })
8141    }
8142}
8143
8144#[cfg(feature = "unstable_elicitation")]
8145impl IntoV2 for crate::v1::ElicitationFormCapabilities {
8146    type Output = super::ElicitationFormCapabilities;
8147
8148    fn into_v2(self) -> Result<Self::Output> {
8149        let Self { meta } = self;
8150        Ok(super::ElicitationFormCapabilities {
8151            meta: meta.into_v2()?,
8152        })
8153    }
8154}
8155
8156#[cfg(feature = "unstable_elicitation")]
8157impl IntoV1 for super::ElicitationUrlCapabilities {
8158    type Output = crate::v1::ElicitationUrlCapabilities;
8159
8160    fn into_v1(self) -> Result<Self::Output> {
8161        let Self { meta } = self;
8162        Ok(crate::v1::ElicitationUrlCapabilities {
8163            meta: meta.into_v1()?,
8164        })
8165    }
8166}
8167
8168#[cfg(feature = "unstable_elicitation")]
8169impl IntoV2 for crate::v1::ElicitationUrlCapabilities {
8170    type Output = super::ElicitationUrlCapabilities;
8171
8172    fn into_v2(self) -> Result<Self::Output> {
8173        let Self { meta } = self;
8174        Ok(super::ElicitationUrlCapabilities {
8175            meta: meta.into_v2()?,
8176        })
8177    }
8178}
8179
8180#[cfg(feature = "unstable_elicitation")]
8181impl IntoV1 for super::ElicitationScope {
8182    type Output = crate::v1::ElicitationScope;
8183
8184    fn into_v1(self) -> Result<Self::Output> {
8185        Ok(match self {
8186            Self::Session(value) => crate::v1::ElicitationScope::Session(value.into_v1()?),
8187            Self::Request(value) => crate::v1::ElicitationScope::Request(value.into_v1()?),
8188        })
8189    }
8190}
8191
8192#[cfg(feature = "unstable_elicitation")]
8193impl IntoV2 for crate::v1::ElicitationScope {
8194    type Output = super::ElicitationScope;
8195
8196    fn into_v2(self) -> Result<Self::Output> {
8197        Ok(match self {
8198            Self::Session(value) => super::ElicitationScope::Session(value.into_v2()?),
8199            Self::Request(value) => super::ElicitationScope::Request(value.into_v2()?),
8200        })
8201    }
8202}
8203
8204#[cfg(feature = "unstable_elicitation")]
8205impl IntoV1 for super::ElicitationSessionScope {
8206    type Output = crate::v1::ElicitationSessionScope;
8207
8208    fn into_v1(self) -> Result<Self::Output> {
8209        let Self {
8210            session_id,
8211            tool_call_id,
8212        } = self;
8213        Ok(crate::v1::ElicitationSessionScope {
8214            session_id: session_id.into_v1()?,
8215            tool_call_id: tool_call_id.into_v1()?,
8216        })
8217    }
8218}
8219
8220#[cfg(feature = "unstable_elicitation")]
8221impl IntoV2 for crate::v1::ElicitationSessionScope {
8222    type Output = super::ElicitationSessionScope;
8223
8224    fn into_v2(self) -> Result<Self::Output> {
8225        let Self {
8226            session_id,
8227            tool_call_id,
8228        } = self;
8229        Ok(super::ElicitationSessionScope {
8230            session_id: session_id.into_v2()?,
8231            tool_call_id: tool_call_id.into_v2()?,
8232        })
8233    }
8234}
8235
8236#[cfg(feature = "unstable_elicitation")]
8237impl IntoV1 for super::ElicitationRequestScope {
8238    type Output = crate::v1::ElicitationRequestScope;
8239
8240    fn into_v1(self) -> Result<Self::Output> {
8241        let Self { request_id } = self;
8242        Ok(crate::v1::ElicitationRequestScope {
8243            request_id: request_id.into_v1()?,
8244        })
8245    }
8246}
8247
8248#[cfg(feature = "unstable_elicitation")]
8249impl IntoV2 for crate::v1::ElicitationRequestScope {
8250    type Output = super::ElicitationRequestScope;
8251
8252    fn into_v2(self) -> Result<Self::Output> {
8253        let Self { request_id } = self;
8254        Ok(super::ElicitationRequestScope {
8255            request_id: request_id.into_v2()?,
8256        })
8257    }
8258}
8259
8260#[cfg(feature = "unstable_elicitation")]
8261impl IntoV1 for super::CreateElicitationRequest {
8262    type Output = crate::v1::CreateElicitationRequest;
8263
8264    fn into_v1(self) -> Result<Self::Output> {
8265        let Self {
8266            mode,
8267            message,
8268            meta,
8269        } = self;
8270        Ok(crate::v1::CreateElicitationRequest {
8271            mode: mode.into_v1()?,
8272            message: message.into_v1()?,
8273            meta: meta.into_v1()?,
8274        })
8275    }
8276}
8277
8278#[cfg(feature = "unstable_elicitation")]
8279impl IntoV2 for crate::v1::CreateElicitationRequest {
8280    type Output = super::CreateElicitationRequest;
8281
8282    fn into_v2(self) -> Result<Self::Output> {
8283        let Self {
8284            mode,
8285            message,
8286            meta,
8287        } = self;
8288        Ok(super::CreateElicitationRequest {
8289            mode: mode.into_v2()?,
8290            message: message.into_v2()?,
8291            meta: meta.into_v2()?,
8292        })
8293    }
8294}
8295
8296#[cfg(feature = "unstable_elicitation")]
8297impl IntoV1 for super::ElicitationMode {
8298    type Output = crate::v1::ElicitationMode;
8299
8300    fn into_v1(self) -> Result<Self::Output> {
8301        Ok(match self {
8302            Self::Form(value) => crate::v1::ElicitationMode::Form(value.into_v1()?),
8303            Self::Url(value) => crate::v1::ElicitationMode::Url(value.into_v1()?),
8304            Self::Other(value) => crate::v1::ElicitationMode::Other(value.into_v1()?),
8305        })
8306    }
8307}
8308
8309#[cfg(feature = "unstable_elicitation")]
8310impl IntoV2 for crate::v1::ElicitationMode {
8311    type Output = super::ElicitationMode;
8312
8313    fn into_v2(self) -> Result<Self::Output> {
8314        Ok(match self {
8315            Self::Form(value) => super::ElicitationMode::Form(value.into_v2()?),
8316            Self::Url(value) => super::ElicitationMode::Url(value.into_v2()?),
8317            Self::Other(value) => super::ElicitationMode::Other(value.into_v2()?),
8318        })
8319    }
8320}
8321
8322#[cfg(feature = "unstable_elicitation")]
8323impl IntoV1 for super::OtherElicitationMode {
8324    type Output = crate::v1::OtherElicitationMode;
8325
8326    fn into_v1(self) -> Result<Self::Output> {
8327        let Self {
8328            mode,
8329            scope,
8330            fields,
8331        } = self;
8332        Ok(crate::v1::OtherElicitationMode {
8333            mode: mode.into_v1()?,
8334            scope: scope.into_v1()?,
8335            fields: fields.into_v1()?,
8336        })
8337    }
8338}
8339
8340#[cfg(feature = "unstable_elicitation")]
8341impl IntoV2 for crate::v1::OtherElicitationMode {
8342    type Output = super::OtherElicitationMode;
8343
8344    fn into_v2(self) -> Result<Self::Output> {
8345        let Self {
8346            mode,
8347            scope,
8348            fields,
8349        } = self;
8350        Ok(super::OtherElicitationMode {
8351            mode: mode.into_v2()?,
8352            scope: scope.into_v2()?,
8353            fields: fields.into_v2()?,
8354        })
8355    }
8356}
8357
8358#[cfg(feature = "unstable_elicitation")]
8359impl IntoV1 for super::ElicitationFormMode {
8360    type Output = crate::v1::ElicitationFormMode;
8361
8362    fn into_v1(self) -> Result<Self::Output> {
8363        let Self {
8364            scope,
8365            requested_schema,
8366        } = self;
8367        Ok(crate::v1::ElicitationFormMode {
8368            scope: scope.into_v1()?,
8369            requested_schema: requested_schema.into_v1()?,
8370        })
8371    }
8372}
8373
8374#[cfg(feature = "unstable_elicitation")]
8375impl IntoV2 for crate::v1::ElicitationFormMode {
8376    type Output = super::ElicitationFormMode;
8377
8378    fn into_v2(self) -> Result<Self::Output> {
8379        let Self {
8380            scope,
8381            requested_schema,
8382        } = self;
8383        Ok(super::ElicitationFormMode {
8384            scope: scope.into_v2()?,
8385            requested_schema: requested_schema.into_v2()?,
8386        })
8387    }
8388}
8389
8390#[cfg(feature = "unstable_elicitation")]
8391impl IntoV1 for super::ElicitationUrlMode {
8392    type Output = crate::v1::ElicitationUrlMode;
8393
8394    fn into_v1(self) -> Result<Self::Output> {
8395        let Self {
8396            scope,
8397            elicitation_id,
8398            url,
8399        } = self;
8400        Ok(crate::v1::ElicitationUrlMode {
8401            scope: scope.into_v1()?,
8402            elicitation_id: elicitation_id.into_v1()?,
8403            url: url.into_v1()?,
8404        })
8405    }
8406}
8407
8408#[cfg(feature = "unstable_elicitation")]
8409impl IntoV2 for crate::v1::ElicitationUrlMode {
8410    type Output = super::ElicitationUrlMode;
8411
8412    fn into_v2(self) -> Result<Self::Output> {
8413        let Self {
8414            scope,
8415            elicitation_id,
8416            url,
8417        } = self;
8418        Ok(super::ElicitationUrlMode {
8419            scope: scope.into_v2()?,
8420            elicitation_id: elicitation_id.into_v2()?,
8421            url: url.into_v2()?,
8422        })
8423    }
8424}
8425
8426#[cfg(feature = "unstable_elicitation")]
8427impl IntoV1 for super::CreateElicitationResponse {
8428    type Output = crate::v1::CreateElicitationResponse;
8429
8430    fn into_v1(self) -> Result<Self::Output> {
8431        let Self { action, meta } = self;
8432        Ok(crate::v1::CreateElicitationResponse {
8433            action: action.into_v1()?,
8434            meta: meta.into_v1()?,
8435        })
8436    }
8437}
8438
8439#[cfg(feature = "unstable_elicitation")]
8440impl IntoV2 for crate::v1::CreateElicitationResponse {
8441    type Output = super::CreateElicitationResponse;
8442
8443    fn into_v2(self) -> Result<Self::Output> {
8444        let Self { action, meta } = self;
8445        Ok(super::CreateElicitationResponse {
8446            action: action.into_v2()?,
8447            meta: meta.into_v2()?,
8448        })
8449    }
8450}
8451
8452#[cfg(feature = "unstable_elicitation")]
8453impl IntoV1 for super::ElicitationAction {
8454    type Output = crate::v1::ElicitationAction;
8455
8456    fn into_v1(self) -> Result<Self::Output> {
8457        Ok(match self {
8458            Self::Accept(value) => crate::v1::ElicitationAction::Accept(value.into_v1()?),
8459            Self::Decline => crate::v1::ElicitationAction::Decline,
8460            Self::Cancel => crate::v1::ElicitationAction::Cancel,
8461            Self::Other(value) => crate::v1::ElicitationAction::Other(value.into_v1()?),
8462        })
8463    }
8464}
8465
8466#[cfg(feature = "unstable_elicitation")]
8467impl IntoV2 for crate::v1::ElicitationAction {
8468    type Output = super::ElicitationAction;
8469
8470    fn into_v2(self) -> Result<Self::Output> {
8471        Ok(match self {
8472            Self::Accept(value) => super::ElicitationAction::Accept(value.into_v2()?),
8473            Self::Decline => super::ElicitationAction::Decline,
8474            Self::Cancel => super::ElicitationAction::Cancel,
8475            Self::Other(value) => super::ElicitationAction::Other(value.into_v2()?),
8476        })
8477    }
8478}
8479
8480#[cfg(feature = "unstable_elicitation")]
8481impl IntoV1 for super::OtherElicitationAction {
8482    type Output = crate::v1::OtherElicitationAction;
8483
8484    fn into_v1(self) -> Result<Self::Output> {
8485        let Self { action, fields } = self;
8486        Ok(crate::v1::OtherElicitationAction {
8487            action: action.into_v1()?,
8488            fields: fields.into_v1()?,
8489        })
8490    }
8491}
8492
8493#[cfg(feature = "unstable_elicitation")]
8494impl IntoV2 for crate::v1::OtherElicitationAction {
8495    type Output = super::OtherElicitationAction;
8496
8497    fn into_v2(self) -> Result<Self::Output> {
8498        let Self { action, fields } = self;
8499        Ok(super::OtherElicitationAction {
8500            action: action.into_v2()?,
8501            fields: fields.into_v2()?,
8502        })
8503    }
8504}
8505
8506#[cfg(feature = "unstable_elicitation")]
8507impl IntoV1 for super::ElicitationAcceptAction {
8508    type Output = crate::v1::ElicitationAcceptAction;
8509
8510    fn into_v1(self) -> Result<Self::Output> {
8511        let Self { content } = self;
8512        Ok(crate::v1::ElicitationAcceptAction {
8513            content: content.into_v1()?,
8514        })
8515    }
8516}
8517
8518#[cfg(feature = "unstable_elicitation")]
8519impl IntoV2 for crate::v1::ElicitationAcceptAction {
8520    type Output = super::ElicitationAcceptAction;
8521
8522    fn into_v2(self) -> Result<Self::Output> {
8523        let Self { content } = self;
8524        Ok(super::ElicitationAcceptAction {
8525            content: content.into_v2()?,
8526        })
8527    }
8528}
8529
8530#[cfg(feature = "unstable_elicitation")]
8531impl IntoV1 for super::ElicitationContentValue {
8532    type Output = crate::v1::ElicitationContentValue;
8533
8534    fn into_v1(self) -> Result<Self::Output> {
8535        Ok(match self {
8536            Self::String(value) => crate::v1::ElicitationContentValue::String(value.into_v1()?),
8537            Self::Integer(value) => crate::v1::ElicitationContentValue::Integer(value.into_v1()?),
8538            Self::Number(value) => crate::v1::ElicitationContentValue::Number(value.into_v1()?),
8539            Self::Boolean(value) => crate::v1::ElicitationContentValue::Boolean(value.into_v1()?),
8540            Self::StringArray(value) => {
8541                crate::v1::ElicitationContentValue::StringArray(value.into_v1()?)
8542            }
8543        })
8544    }
8545}
8546
8547#[cfg(feature = "unstable_elicitation")]
8548impl IntoV2 for crate::v1::ElicitationContentValue {
8549    type Output = super::ElicitationContentValue;
8550
8551    fn into_v2(self) -> Result<Self::Output> {
8552        Ok(match self {
8553            Self::String(value) => super::ElicitationContentValue::String(value.into_v2()?),
8554            Self::Integer(value) => super::ElicitationContentValue::Integer(value.into_v2()?),
8555            Self::Number(value) => super::ElicitationContentValue::Number(value.into_v2()?),
8556            Self::Boolean(value) => super::ElicitationContentValue::Boolean(value.into_v2()?),
8557            Self::StringArray(value) => {
8558                super::ElicitationContentValue::StringArray(value.into_v2()?)
8559            }
8560        })
8561    }
8562}
8563
8564#[cfg(feature = "unstable_elicitation")]
8565impl IntoV1 for super::CompleteElicitationNotification {
8566    type Output = crate::v1::CompleteElicitationNotification;
8567
8568    fn into_v1(self) -> Result<Self::Output> {
8569        let Self {
8570            elicitation_id,
8571            meta,
8572        } = self;
8573        Ok(crate::v1::CompleteElicitationNotification {
8574            elicitation_id: elicitation_id.into_v1()?,
8575            meta: meta.into_v1()?,
8576        })
8577    }
8578}
8579
8580#[cfg(feature = "unstable_elicitation")]
8581impl IntoV2 for crate::v1::CompleteElicitationNotification {
8582    type Output = super::CompleteElicitationNotification;
8583
8584    fn into_v2(self) -> Result<Self::Output> {
8585        let Self {
8586            elicitation_id,
8587            meta,
8588        } = self;
8589        Ok(super::CompleteElicitationNotification {
8590            elicitation_id: elicitation_id.into_v2()?,
8591            meta: meta.into_v2()?,
8592        })
8593    }
8594}
8595
8596impl IntoV1 for super::ContentBlock {
8597    type Output = crate::v1::ContentBlock;
8598
8599    fn into_v1(self) -> Result<Self::Output> {
8600        Ok(match self {
8601            Self::Text(value) => crate::v1::ContentBlock::Text(value.into_v1()?),
8602            Self::Image(value) => crate::v1::ContentBlock::Image(value.into_v1()?),
8603            Self::Audio(value) => crate::v1::ContentBlock::Audio(value.into_v1()?),
8604            Self::ResourceLink(value) => crate::v1::ContentBlock::ResourceLink(value.into_v1()?),
8605            Self::Resource(value) => crate::v1::ContentBlock::Resource(value.into_v1()?),
8606            Self::Other(value) => {
8607                return Err(unknown_v2_enum_variant("ContentBlock", &value.type_));
8608            }
8609        })
8610    }
8611}
8612
8613impl IntoV2 for crate::v1::ContentBlock {
8614    type Output = super::ContentBlock;
8615
8616    fn into_v2(self) -> Result<Self::Output> {
8617        Ok(match self {
8618            Self::Text(value) => super::ContentBlock::Text(value.into_v2()?),
8619            Self::Image(value) => super::ContentBlock::Image(value.into_v2()?),
8620            Self::Audio(value) => super::ContentBlock::Audio(value.into_v2()?),
8621            Self::ResourceLink(value) => super::ContentBlock::ResourceLink(value.into_v2()?),
8622            Self::Resource(value) => super::ContentBlock::Resource(value.into_v2()?),
8623        })
8624    }
8625}
8626
8627impl IntoV1 for super::TextContent {
8628    type Output = crate::v1::TextContent;
8629
8630    fn into_v1(self) -> Result<Self::Output> {
8631        let Self {
8632            annotations,
8633            text,
8634            meta,
8635        } = self;
8636        Ok(crate::v1::TextContent {
8637            annotations: into_v1_default_on_error(annotations),
8638            text: text.into_v1()?,
8639            meta: meta.into_v1()?,
8640        })
8641    }
8642}
8643
8644impl IntoV2 for crate::v1::TextContent {
8645    type Output = super::TextContent;
8646
8647    fn into_v2(self) -> Result<Self::Output> {
8648        let Self {
8649            annotations,
8650            text,
8651            meta,
8652        } = self;
8653        Ok(super::TextContent {
8654            annotations: into_v2_default_on_error(annotations),
8655            text: text.into_v2()?,
8656            meta: meta.into_v2()?,
8657        })
8658    }
8659}
8660
8661impl IntoV1 for super::ImageContent {
8662    type Output = crate::v1::ImageContent;
8663
8664    fn into_v1(self) -> Result<Self::Output> {
8665        let Self {
8666            annotations,
8667            data,
8668            mime_type,
8669            uri,
8670            meta,
8671        } = self;
8672        Ok(crate::v1::ImageContent {
8673            annotations: into_v1_default_on_error(annotations),
8674            data: data.into_v1()?,
8675            mime_type: mime_type.into_v1()?,
8676            uri: uri.into_v1()?,
8677            meta: meta.into_v1()?,
8678        })
8679    }
8680}
8681
8682impl IntoV2 for crate::v1::ImageContent {
8683    type Output = super::ImageContent;
8684
8685    fn into_v2(self) -> Result<Self::Output> {
8686        let Self {
8687            annotations,
8688            data,
8689            mime_type,
8690            uri,
8691            meta,
8692        } = self;
8693        Ok(super::ImageContent {
8694            annotations: into_v2_default_on_error(annotations),
8695            data: data.into_v2()?,
8696            mime_type: mime_type.into_v2()?,
8697            uri: uri.into_v2()?,
8698            meta: meta.into_v2()?,
8699        })
8700    }
8701}
8702
8703impl IntoV1 for super::AudioContent {
8704    type Output = crate::v1::AudioContent;
8705
8706    fn into_v1(self) -> Result<Self::Output> {
8707        let Self {
8708            annotations,
8709            data,
8710            mime_type,
8711            meta,
8712        } = self;
8713        Ok(crate::v1::AudioContent {
8714            annotations: into_v1_default_on_error(annotations),
8715            data: data.into_v1()?,
8716            mime_type: mime_type.into_v1()?,
8717            meta: meta.into_v1()?,
8718        })
8719    }
8720}
8721
8722impl IntoV2 for crate::v1::AudioContent {
8723    type Output = super::AudioContent;
8724
8725    fn into_v2(self) -> Result<Self::Output> {
8726        let Self {
8727            annotations,
8728            data,
8729            mime_type,
8730            meta,
8731        } = self;
8732        Ok(super::AudioContent {
8733            annotations: into_v2_default_on_error(annotations),
8734            data: data.into_v2()?,
8735            mime_type: mime_type.into_v2()?,
8736            meta: meta.into_v2()?,
8737        })
8738    }
8739}
8740
8741impl IntoV1 for super::EmbeddedResource {
8742    type Output = crate::v1::EmbeddedResource;
8743
8744    fn into_v1(self) -> Result<Self::Output> {
8745        let Self {
8746            annotations,
8747            resource,
8748            meta,
8749        } = self;
8750        Ok(crate::v1::EmbeddedResource {
8751            annotations: into_v1_default_on_error(annotations),
8752            resource: resource.into_v1()?,
8753            meta: meta.into_v1()?,
8754        })
8755    }
8756}
8757
8758impl IntoV2 for crate::v1::EmbeddedResource {
8759    type Output = super::EmbeddedResource;
8760
8761    fn into_v2(self) -> Result<Self::Output> {
8762        let Self {
8763            annotations,
8764            resource,
8765            meta,
8766        } = self;
8767        Ok(super::EmbeddedResource {
8768            annotations: into_v2_default_on_error(annotations),
8769            resource: resource.into_v2()?,
8770            meta: meta.into_v2()?,
8771        })
8772    }
8773}
8774
8775impl IntoV1 for super::EmbeddedResourceResource {
8776    type Output = crate::v1::EmbeddedResourceResource;
8777
8778    fn into_v1(self) -> Result<Self::Output> {
8779        Ok(match self {
8780            Self::TextResourceContents(value) => {
8781                crate::v1::EmbeddedResourceResource::TextResourceContents(value.into_v1()?)
8782            }
8783            Self::BlobResourceContents(value) => {
8784                crate::v1::EmbeddedResourceResource::BlobResourceContents(value.into_v1()?)
8785            }
8786        })
8787    }
8788}
8789
8790impl IntoV2 for crate::v1::EmbeddedResourceResource {
8791    type Output = super::EmbeddedResourceResource;
8792
8793    fn into_v2(self) -> Result<Self::Output> {
8794        Ok(match self {
8795            Self::TextResourceContents(value) => {
8796                super::EmbeddedResourceResource::TextResourceContents(value.into_v2()?)
8797            }
8798            Self::BlobResourceContents(value) => {
8799                super::EmbeddedResourceResource::BlobResourceContents(value.into_v2()?)
8800            }
8801        })
8802    }
8803}
8804
8805impl IntoV1 for super::TextResourceContents {
8806    type Output = crate::v1::TextResourceContents;
8807
8808    fn into_v1(self) -> Result<Self::Output> {
8809        let Self {
8810            mime_type,
8811            text,
8812            uri,
8813            meta,
8814        } = self;
8815        Ok(crate::v1::TextResourceContents {
8816            mime_type: mime_type.into_v1()?,
8817            text: text.into_v1()?,
8818            uri: uri.into_v1()?,
8819            meta: meta.into_v1()?,
8820        })
8821    }
8822}
8823
8824impl IntoV2 for crate::v1::TextResourceContents {
8825    type Output = super::TextResourceContents;
8826
8827    fn into_v2(self) -> Result<Self::Output> {
8828        let Self {
8829            mime_type,
8830            text,
8831            uri,
8832            meta,
8833        } = self;
8834        Ok(super::TextResourceContents {
8835            mime_type: mime_type.into_v2()?,
8836            text: text.into_v2()?,
8837            uri: uri.into_v2()?,
8838            meta: meta.into_v2()?,
8839        })
8840    }
8841}
8842
8843impl IntoV1 for super::BlobResourceContents {
8844    type Output = crate::v1::BlobResourceContents;
8845
8846    fn into_v1(self) -> Result<Self::Output> {
8847        let Self {
8848            blob,
8849            mime_type,
8850            uri,
8851            meta,
8852        } = self;
8853        Ok(crate::v1::BlobResourceContents {
8854            blob: blob.into_v1()?,
8855            mime_type: mime_type.into_v1()?,
8856            uri: uri.into_v1()?,
8857            meta: meta.into_v1()?,
8858        })
8859    }
8860}
8861
8862impl IntoV2 for crate::v1::BlobResourceContents {
8863    type Output = super::BlobResourceContents;
8864
8865    fn into_v2(self) -> Result<Self::Output> {
8866        let Self {
8867            blob,
8868            mime_type,
8869            uri,
8870            meta,
8871        } = self;
8872        Ok(super::BlobResourceContents {
8873            blob: blob.into_v2()?,
8874            mime_type: mime_type.into_v2()?,
8875            uri: uri.into_v2()?,
8876            meta: meta.into_v2()?,
8877        })
8878    }
8879}
8880
8881impl IntoV1 for super::ResourceLink {
8882    type Output = crate::v1::ResourceLink;
8883
8884    fn into_v1(self) -> Result<Self::Output> {
8885        let Self {
8886            annotations,
8887            description,
8888            icons,
8889            mime_type,
8890            name,
8891            size,
8892            title,
8893            uri,
8894            meta,
8895        } = self;
8896
8897        if matches!(icons.as_ref(), Some(icons) if !icons.is_empty()) {
8898            return Err(ProtocolConversionError::new(
8899                "v2 ResourceLink.icons cannot be represented in v1",
8900            ));
8901        }
8902
8903        Ok(crate::v1::ResourceLink {
8904            annotations: into_v1_default_on_error(annotations),
8905            description: description.into_v1()?,
8906            mime_type: mime_type.into_v1()?,
8907            name: name.into_v1()?,
8908            size: size.into_v1()?,
8909            title: title.into_v1()?,
8910            uri: uri.into_v1()?,
8911            meta: meta.into_v1()?,
8912        })
8913    }
8914}
8915
8916impl IntoV2 for crate::v1::ResourceLink {
8917    type Output = super::ResourceLink;
8918
8919    fn into_v2(self) -> Result<Self::Output> {
8920        let Self {
8921            annotations,
8922            description,
8923            mime_type,
8924            name,
8925            size,
8926            title,
8927            uri,
8928            meta,
8929        } = self;
8930        Ok(super::ResourceLink {
8931            annotations: into_v2_default_on_error(annotations),
8932            description: description.into_v2()?,
8933            icons: None,
8934            mime_type: mime_type.into_v2()?,
8935            name: name.into_v2()?,
8936            size: size.into_v2()?,
8937            title: title.into_v2()?,
8938            uri: uri.into_v2()?,
8939            meta: meta.into_v2()?,
8940        })
8941    }
8942}
8943
8944impl IntoV1 for super::Annotations {
8945    type Output = crate::v1::Annotations;
8946
8947    fn into_v1(self) -> Result<Self::Output> {
8948        let Self {
8949            audience,
8950            last_modified,
8951            priority,
8952            meta,
8953        } = self;
8954        Ok(crate::v1::Annotations {
8955            audience: option_vec_into_v1_skip_errors(audience),
8956            last_modified: last_modified.into_v1()?,
8957            priority: priority.into_v1()?,
8958            meta: meta.into_v1()?,
8959        })
8960    }
8961}
8962
8963impl IntoV2 for crate::v1::Annotations {
8964    type Output = super::Annotations;
8965
8966    fn into_v2(self) -> Result<Self::Output> {
8967        let Self {
8968            audience,
8969            last_modified,
8970            priority,
8971            meta,
8972        } = self;
8973        Ok(super::Annotations {
8974            audience: option_vec_into_v2_skip_errors(audience),
8975            last_modified: last_modified.into_v2()?,
8976            priority: priority.into_v2()?,
8977            meta: meta.into_v2()?,
8978        })
8979    }
8980}
8981
8982impl IntoV1 for super::Role {
8983    type Output = crate::v1::Role;
8984
8985    fn into_v1(self) -> Result<Self::Output> {
8986        Ok(match self {
8987            Self::Assistant => crate::v1::Role::Assistant,
8988            Self::User => crate::v1::Role::User,
8989            Self::Other(value) => return Err(unknown_v2_enum_variant("Role", &value)),
8990        })
8991    }
8992}
8993
8994impl IntoV2 for crate::v1::Role {
8995    type Output = super::Role;
8996
8997    fn into_v2(self) -> Result<Self::Output> {
8998        Ok(match self {
8999            Self::Assistant => super::Role::Assistant,
9000            Self::User => super::Role::User,
9001        })
9002    }
9003}
9004
9005#[cfg(test)]
9006mod tests {
9007    use super::*;
9008    use crate::{v1, v2};
9009
9010    /// Round-trip a v1 value through v2 and back, asserting equality.
9011    ///
9012    /// This catches dropped fields, renamed fields, and missing enum
9013    /// variants in either direction of the conversion as soon as v1 and v2
9014    /// diverge.
9015    fn assert_v1_round_trip<T1, T2>(value: T1)
9016    where
9017        T1: IntoV2<Output = T2> + Clone + std::fmt::Debug + PartialEq,
9018        T2: IntoV1<Output = T1>,
9019    {
9020        let original = value.clone();
9021        let as_v2 = v1_to_v2(value).expect("v1 -> v2 conversion failed");
9022        let back = v2_to_v1(as_v2).expect("v2 -> v1 conversion failed");
9023        assert_eq!(
9024            original, back,
9025            "value did not survive v1 -> v2 -> v1 round trip"
9026        );
9027    }
9028
9029    /// Round-trip a v2 value through v1 and back, asserting equality.
9030    fn assert_v2_round_trip<T2, T1>(value: T2)
9031    where
9032        T2: IntoV1<Output = T1> + Clone + std::fmt::Debug + PartialEq,
9033        T1: IntoV2<Output = T2>,
9034    {
9035        let original = value.clone();
9036        let as_v1 = v2_to_v1(value).expect("v2 -> v1 conversion failed");
9037        let back = v1_to_v2(as_v1).expect("v1 -> v2 conversion failed");
9038        assert_eq!(
9039            original, back,
9040            "value did not survive v2 -> v1 -> v2 round trip"
9041        );
9042    }
9043
9044    /// While v1 and v2 are structurally identical, JSON produced by either
9045    /// module must be byte-equal after a conversion. This is a cheap insurance
9046    /// against accidental field renames or shape drift in conversions.
9047    ///
9048    /// Starts from a v1 value, converts forward to v2 and asserts JSON
9049    /// equality, then converts back to v1 and asserts JSON equality again.
9050    /// Catches shape drift in both directions of the conversion.
9051    fn assert_json_eq_after_v1_to_v2<T1, T2>(value: T1)
9052    where
9053        T1: IntoV2<Output = T2> + serde::Serialize + Clone,
9054        T2: IntoV1<Output = T1> + serde::Serialize,
9055    {
9056        let v1_json = serde_json::to_value(&value).expect("v1 serialize");
9057        let as_v2 = v1_to_v2(value).expect("v1 -> v2 conversion");
9058        let v2_json = serde_json::to_value(&as_v2).expect("v2 serialize");
9059        assert_eq!(
9060            v1_json, v2_json,
9061            "JSON shape diverged after v1 -> v2 conversion"
9062        );
9063
9064        let back_to_v1 = v2_to_v1(as_v2).expect("v2 -> v1 conversion");
9065        let v1_json_after =
9066            serde_json::to_value(&back_to_v1).expect("v1 serialize after round trip");
9067        assert_eq!(
9068            v2_json, v1_json_after,
9069            "JSON shape diverged after v2 -> v1 conversion"
9070        );
9071    }
9072
9073    /// Mirror of [`assert_json_eq_after_v1_to_v2`] that starts from a v2 value.
9074    /// Useful when the natural starting point is a v2 type (for example when
9075    /// the type only exists today in v2's draft API surface).
9076    fn assert_json_eq_after_v2_to_v1<T2, T1>(value: T2)
9077    where
9078        T2: IntoV1<Output = T1> + serde::Serialize + Clone,
9079        T1: IntoV2<Output = T2> + serde::Serialize,
9080    {
9081        let v2_json = serde_json::to_value(&value).expect("v2 serialize");
9082        let as_v1 = v2_to_v1(value).expect("v2 -> v1 conversion");
9083        let v1_json = serde_json::to_value(&as_v1).expect("v1 serialize");
9084        assert_eq!(
9085            v2_json, v1_json,
9086            "JSON shape diverged after v2 -> v1 conversion"
9087        );
9088
9089        let back_to_v2 = v1_to_v2(as_v1).expect("v1 -> v2 conversion");
9090        let v2_json_after =
9091            serde_json::to_value(&back_to_v2).expect("v2 serialize after round trip");
9092        assert_eq!(
9093            v1_json, v2_json_after,
9094            "JSON shape diverged after v1 -> v2 conversion"
9095        );
9096    }
9097
9098    fn assert_v2_to_v1_error<T>(value: T, expected: &str)
9099    where
9100        T: IntoV1,
9101        T::Output: std::fmt::Debug,
9102    {
9103        let error = v2_to_v1(value).unwrap_err();
9104        assert_eq!(error.message(), expected);
9105    }
9106
9107    fn assert_v2_to_v1_many_error<T>(value: T, expected: &str)
9108    where
9109        T: IntoV1Many,
9110        T::Output: std::fmt::Debug,
9111    {
9112        let error = v2_to_v1_many(value).unwrap_err();
9113        assert_eq!(error.message(), expected);
9114    }
9115
9116    fn assert_v1_to_v2_error<T>(value: T, expected: &str)
9117    where
9118        T: IntoV2,
9119        T::Output: std::fmt::Debug,
9120    {
9121        let error = v1_to_v2(value).unwrap_err();
9122        assert_eq!(error.message(), expected);
9123    }
9124
9125    #[test]
9126    fn round_trips_session_config_option_categories() {
9127        for category in [
9128            v1::SessionConfigOptionCategory::Mode,
9129            v1::SessionConfigOptionCategory::Model,
9130            v1::SessionConfigOptionCategory::ModelConfig,
9131            v1::SessionConfigOptionCategory::ThoughtLevel,
9132            v1::SessionConfigOptionCategory::Other("_custom_category".to_string()),
9133        ] {
9134            assert_v1_round_trip::<v1::SessionConfigOptionCategory, v2::SessionConfigOptionCategory>(
9135                category,
9136            );
9137        }
9138
9139        for category in [
9140            v2::SessionConfigOptionCategory::Mode,
9141            v2::SessionConfigOptionCategory::Model,
9142            v2::SessionConfigOptionCategory::ModelConfig,
9143            v2::SessionConfigOptionCategory::ThoughtLevel,
9144            v2::SessionConfigOptionCategory::Other("_custom_category".to_string()),
9145        ] {
9146            assert_v2_round_trip::<v2::SessionConfigOptionCategory, v1::SessionConfigOptionCategory>(
9147                category,
9148            );
9149        }
9150    }
9151
9152    #[test]
9153    fn converts_v2_initialize_request_to_v1_without_serde() {
9154        let request = v2::InitializeRequest::new(
9155            ProtocolVersion::V2,
9156            v2::Implementation::new("test-client", "1.0.0"),
9157        );
9158
9159        let converted: v1::InitializeRequest = v2_to_v1(request).unwrap();
9160
9161        assert_eq!(converted.protocol_version, ProtocolVersion::V2);
9162        assert_eq!(
9163            converted
9164                .client_info
9165                .as_ref()
9166                .map(|info| info.name.as_str()),
9167            Some("test-client")
9168        );
9169    }
9170
9171    #[test]
9172    fn v1_initialize_request_without_client_info_does_not_convert_to_v2() {
9173        let request = v1::InitializeRequest::new(ProtocolVersion::V1);
9174
9175        assert_v1_to_v2_error(
9176            request,
9177            "v1 InitializeRequest without `clientInfo` cannot be represented in v2",
9178        );
9179    }
9180
9181    #[test]
9182    fn v1_initialize_response_without_agent_info_does_not_convert_to_v2() {
9183        let response = v1::InitializeResponse::new(ProtocolVersion::V1);
9184
9185        assert_v1_to_v2_error(
9186            response,
9187            "v1 InitializeResponse without `agentInfo` cannot be represented in v2",
9188        );
9189    }
9190
9191    #[test]
9192    fn round_trips_initialize_request() {
9193        let client_capabilities = v1::ClientCapabilities::new().session(
9194            v1::ClientSessionCapabilities::new().config_options(
9195                v1::SessionConfigOptionsCapabilities::new()
9196                    .boolean(v1::BooleanConfigOptionCapabilities::new()),
9197            ),
9198        );
9199
9200        let request = v1::InitializeRequest::new(ProtocolVersion::V1)
9201            .client_capabilities(client_capabilities)
9202            .client_info(v1::Implementation::new("test-client", "1.0.0").title("Test Client"));
9203
9204        assert_v1_round_trip::<v1::InitializeRequest, v2::InitializeRequest>(request.clone());
9205        let converted: v2::InitializeRequest =
9206            v1_to_v2(request).expect("v1 -> v2 conversion failed");
9207        let converted_capabilities =
9208            serde_json::to_value(&converted.capabilities).expect("v2 serialize");
9209        assert_eq!(converted_capabilities.get("fs"), None);
9210        assert_eq!(converted_capabilities.get("terminal"), None);
9211        let converted_json = serde_json::to_value(&converted).expect("v2 serialize");
9212        assert_eq!(converted_json.get("clientInfo"), None);
9213        assert_eq!(converted_json.get("implementation"), None);
9214        assert!(converted_json.get("info").is_some());
9215    }
9216
9217    #[test]
9218    fn round_trips_initialize_response() {
9219        let session_capabilities = v1::SessionCapabilities::new()
9220            .list(v1::SessionListCapabilities::new())
9221            .resume(v1::SessionResumeCapabilities::new())
9222            .close(v1::SessionCloseCapabilities::new());
9223        let response = v1::InitializeResponse::new(ProtocolVersion::V1)
9224            .agent_capabilities(
9225                v1::AgentCapabilities::new()
9226                    .load_session(true)
9227                    .session_capabilities(session_capabilities)
9228                    .auth(v1::AgentAuthCapabilities::new().logout(v1::LogoutCapabilities::new())),
9229            )
9230            .agent_info(v1::Implementation::new("test-agent", "2.0.0").title("Test Agent"));
9231        assert_v1_round_trip::<v1::InitializeResponse, v2::InitializeResponse>(response.clone());
9232        let converted: v2::InitializeResponse =
9233            v1_to_v2(response).expect("v1 -> v2 conversion failed");
9234        let converted_json = serde_json::to_value(&converted).expect("v2 serialize");
9235        assert_eq!(converted_json.get("agentCapabilities"), None);
9236        assert!(converted_json.get("capabilities").is_some());
9237        assert_eq!(converted_json.get("agentInfo"), None);
9238        assert_eq!(converted_json.get("implementation"), None);
9239        assert!(converted_json.get("info").is_some());
9240        assert_eq!(converted_json.pointer("/capabilities/loadSession"), None);
9241    }
9242
9243    #[test]
9244    fn required_v2_session_methods_convert_to_v1_capability_markers() {
9245        let v1_capabilities = v1::AgentCapabilities::new().load_session(true);
9246
9247        let v2_capabilities: v2::AgentCapabilities =
9248            v1_to_v2(v1_capabilities).expect("v1 -> v2 conversion");
9249        let session = v2_capabilities
9250            .session
9251            .as_ref()
9252            .expect("v1 capabilities imply v2 session support");
9253        assert!(session.delete.is_none());
9254        let v2_json = serde_json::to_value(&v2_capabilities).expect("v2 serialize");
9255        assert_eq!(v2_json.get("loadSession"), None);
9256        assert_eq!(v2_json.pointer("/session/load"), None);
9257        assert_eq!(v2_json.pointer("/session/list"), None);
9258        assert_eq!(v2_json.pointer("/session/resume"), None);
9259        assert_eq!(v2_json.pointer("/session/close"), None);
9260
9261        let v1_after: v1::AgentCapabilities =
9262            v2_to_v1(v2_capabilities).expect("v2 -> v1 conversion");
9263        assert!(v1_after.load_session);
9264        assert!(v1_after.session_capabilities.list.is_some());
9265        assert!(v1_after.session_capabilities.resume.is_some());
9266        assert!(v1_after.session_capabilities.close.is_some());
9267    }
9268
9269    #[test]
9270    fn v2_agent_capabilities_without_session_do_not_convert_to_v1() {
9271        let error = v2::AgentCapabilities::new().into_v1().unwrap_err();
9272        assert_eq!(
9273            error.message(),
9274            "v2 AgentCapabilities without `session` cannot be represented in v1"
9275        );
9276    }
9277
9278    #[test]
9279    fn v2_auth_logout_is_baseline_not_capability_marker() {
9280        let v2_auth = v2::AgentAuthCapabilities::new();
9281        let v2_json = serde_json::to_value(&v2_auth).expect("v2 serialize");
9282        assert_eq!(v2_json.get("logout"), None);
9283
9284        let v1_auth: v1::AgentAuthCapabilities = v2_to_v1(v2_auth).expect("v2 -> v1 conversion");
9285        assert!(v1_auth.logout.is_some());
9286
9287        let v1_auth_without_logout = v1::AgentAuthCapabilities::new();
9288        let v2_auth: v2::AgentAuthCapabilities =
9289            v1_to_v2(v1_auth_without_logout).expect("v1 -> v2 conversion");
9290        let v2_json = serde_json::to_value(&v2_auth).expect("v2 serialize");
9291        assert_eq!(v2_json.get("logout"), None);
9292    }
9293
9294    #[test]
9295    fn v2_session_capabilities_convert_to_v1_agent_capability_parts() {
9296        let parts = v2::SessionCapabilities::new()
9297            .prompt(v2::PromptCapabilities::new().image(v2::PromptImageCapabilities::new()))
9298            .mcp(v2::McpCapabilities::new().http(v2::McpHttpCapabilities::new()))
9299            .into_v1()
9300            .expect("v2 session capabilities -> v1 parts");
9301
9302        assert!(parts.session_capabilities.list.is_some());
9303        assert!(parts.session_capabilities.resume.is_some());
9304        assert!(parts.session_capabilities.close.is_some());
9305        assert!(parts.prompt_capabilities.image);
9306        assert!(parts.load_session);
9307        assert!(parts.mcp_capabilities.http);
9308    }
9309
9310    #[test]
9311    fn v1_prompt_capability_bools_convert_to_v2_objects() {
9312        let v1_capabilities = v1::PromptCapabilities::new()
9313            .image(true)
9314            .audio(true)
9315            .embedded_context(true);
9316
9317        let v2_capabilities: v2::PromptCapabilities =
9318            v1_to_v2(v1_capabilities).expect("v1 -> v2 conversion");
9319        let v2_json = serde_json::to_value(&v2_capabilities).expect("v2 serialize");
9320        assert_eq!(v2_json.pointer("/image"), Some(&serde_json::json!({})));
9321        assert_eq!(v2_json.pointer("/audio"), Some(&serde_json::json!({})));
9322        assert_eq!(
9323            v2_json.pointer("/embeddedContext"),
9324            Some(&serde_json::json!({}))
9325        );
9326
9327        let v1_after: v1::PromptCapabilities =
9328            v2_to_v1(v2_capabilities).expect("v2 -> v1 conversion");
9329        assert!(v1_after.image);
9330        assert!(v1_after.audio);
9331        assert!(v1_after.embedded_context);
9332    }
9333
9334    #[test]
9335    fn v1_mcp_capabilities_convert_to_v2_transport_objects() {
9336        let v1_capabilities = v1::McpCapabilities::new().http(true).sse(true);
9337
9338        let v2_capabilities: v2::McpCapabilities =
9339            v1_to_v2(v1_capabilities).expect("v1 -> v2 conversion");
9340        let v2_json = serde_json::to_value(&v2_capabilities).expect("v2 serialize");
9341        assert_eq!(v2_json.pointer("/stdio"), Some(&serde_json::json!({})));
9342        assert_eq!(v2_json.pointer("/http"), Some(&serde_json::json!({})));
9343        assert_eq!(v2_json.pointer("/sse"), None);
9344
9345        let v1_after: v1::McpCapabilities = v2_to_v1(v2_capabilities).expect("v2 -> v1 conversion");
9346        assert!(v1_after.http);
9347        assert!(!v1_after.sse);
9348    }
9349
9350    #[cfg(feature = "unstable_mcp_over_acp")]
9351    #[test]
9352    fn v1_mcp_acp_capability_bool_converts_to_v2_object() {
9353        let v1_capabilities = v1::McpCapabilities::new().acp(true);
9354
9355        let v2_capabilities: v2::McpCapabilities =
9356            v1_to_v2(v1_capabilities).expect("v1 -> v2 conversion");
9357        let v2_json = serde_json::to_value(&v2_capabilities).expect("v2 serialize");
9358        assert_eq!(v2_json.pointer("/acp"), Some(&serde_json::json!({})));
9359
9360        let v1_after: v1::McpCapabilities = v2_to_v1(v2_capabilities).expect("v2 -> v1 conversion");
9361        assert!(v1_after.acp);
9362    }
9363
9364    #[cfg(feature = "unstable_auth_methods")]
9365    #[test]
9366    fn v1_auth_terminal_capability_bool_converts_to_v2_object() {
9367        let v1_capabilities = v1::AuthCapabilities::new().terminal(true);
9368
9369        let v2_capabilities: v2::AuthCapabilities =
9370            v1_to_v2(v1_capabilities).expect("v1 -> v2 conversion");
9371        let v2_json = serde_json::to_value(&v2_capabilities).expect("v2 serialize");
9372        assert_eq!(v2_json.pointer("/terminal"), Some(&serde_json::json!({})));
9373
9374        let v1_after: v1::AuthCapabilities =
9375            v2_to_v1(v2_capabilities).expect("v2 -> v1 conversion");
9376        assert!(v1_after.terminal);
9377    }
9378
9379    #[cfg(feature = "unstable_auth_methods")]
9380    #[test]
9381    fn auth_method_terminal_env_converts_between_map_and_variable_array() {
9382        let mut env = HashMap::new();
9383        env.insert("TERM".to_string(), "xterm-256color".to_string());
9384        env.insert("API_KEY".to_string(), "secret".to_string());
9385
9386        let v1_method = v1::AuthMethodTerminal::new("tui-auth", "Terminal Auth").env(env);
9387        let v2_method: v2::AuthMethodTerminal = v1_to_v2(v1_method).expect("v1 -> v2 conversion");
9388        let v2_json = serde_json::to_value(&v2_method).expect("v2 serialize");
9389        assert_eq!(
9390            v2_json.pointer("/env"),
9391            Some(&serde_json::json!([
9392                {
9393                    "name": "API_KEY",
9394                    "value": "secret"
9395                },
9396                {
9397                    "name": "TERM",
9398                    "value": "xterm-256color"
9399                }
9400            ]))
9401        );
9402
9403        let v1_after: v1::AuthMethodTerminal = v2_to_v1(v2_method).expect("v2 -> v1 conversion");
9404        assert_eq!(
9405            v1_after.env.get("TERM").map(String::as_str),
9406            Some("xterm-256color")
9407        );
9408        assert_eq!(
9409            v1_after.env.get("API_KEY").map(String::as_str),
9410            Some("secret")
9411        );
9412    }
9413
9414    #[cfg(feature = "unstable_auth_methods")]
9415    #[test]
9416    fn auth_method_terminal_duplicate_env_names_do_not_convert_to_v1() {
9417        let v2_method = v2::AuthMethodTerminal::new("tui-auth", "Terminal Auth").env(vec![
9418            v2::EnvVariable::new("TERM", "xterm"),
9419            v2::EnvVariable::new("TERM", "xterm-256color"),
9420        ]);
9421
9422        assert_v2_to_v1_error(
9423            v2_method,
9424            "v2 AuthMethodTerminal env variable `TERM` is duplicated and cannot be represented in v1",
9425        );
9426    }
9427
9428    #[test]
9429    fn v1_client_fs_and_terminal_capabilities_are_removed_in_v2() {
9430        let v1_capabilities =
9431            v1::ClientCapabilities::new()
9432                .terminal(true)
9433                .fs(v1::FileSystemCapabilities::new()
9434                    .read_text_file(true)
9435                    .write_text_file(true));
9436
9437        let v2_capabilities: v2::ClientCapabilities =
9438            v1_to_v2(v1_capabilities).expect("v1 -> v2 conversion");
9439        let v2_json = serde_json::to_value(&v2_capabilities).expect("v2 serialize");
9440        assert_eq!(
9441            v2_json.get("fs"),
9442            None,
9443            "v2 ClientCapabilities must not include filesystem capabilities"
9444        );
9445        assert_eq!(
9446            v2_json.get("terminal"),
9447            None,
9448            "v2 ClientCapabilities must not include terminal capabilities"
9449        );
9450
9451        let v1_after: v1::ClientCapabilities =
9452            v2_to_v1(v2_capabilities).expect("v2 -> v1 conversion");
9453        assert!(!v1_after.fs.read_text_file);
9454        assert!(!v1_after.fs.write_text_file);
9455        assert!(!v1_after.terminal);
9456    }
9457
9458    #[test]
9459    fn v2_client_capabilities_default_to_v1_boolean_config_option_support() {
9460        let v2_capabilities = v2::ClientCapabilities::new();
9461
9462        let v1_capabilities: v1::ClientCapabilities =
9463            v2_to_v1(v2_capabilities).expect("v2 -> v1 conversion");
9464
9465        assert!(
9466            v1_capabilities
9467                .session
9468                .and_then(|session| session.config_options)
9469                .and_then(|config_options| config_options.boolean)
9470                .is_some()
9471        );
9472    }
9473
9474    #[test]
9475    fn v1_client_fs_and_terminal_methods_do_not_convert_to_v2() {
9476        assert_v1_to_v2_error(
9477            v1::AgentRequest::WriteTextFileRequest(v1::WriteTextFileRequest::new(
9478                "sess",
9479                "/workspace/file.txt",
9480                "contents",
9481            )),
9482            "v1 AgentRequest variant `fs/write_text_file` cannot be represented in v2",
9483        );
9484        assert_v1_to_v2_error(
9485            v1::AgentRequest::ReadTextFileRequest(v1::ReadTextFileRequest::new(
9486                "sess",
9487                "/workspace/file.txt",
9488            )),
9489            "v1 AgentRequest variant `fs/read_text_file` cannot be represented in v2",
9490        );
9491        assert_v1_to_v2_error(
9492            v1::AgentRequest::CreateTerminalRequest(v1::CreateTerminalRequest::new("sess", "echo")),
9493            "v1 AgentRequest variant `terminal/create` cannot be represented in v2",
9494        );
9495        assert_v1_to_v2_error(
9496            v1::AgentRequest::TerminalOutputRequest(v1::TerminalOutputRequest::new("sess", "term")),
9497            "v1 AgentRequest variant `terminal/output` cannot be represented in v2",
9498        );
9499        assert_v1_to_v2_error(
9500            v1::AgentRequest::ReleaseTerminalRequest(v1::ReleaseTerminalRequest::new(
9501                "sess", "term",
9502            )),
9503            "v1 AgentRequest variant `terminal/release` cannot be represented in v2",
9504        );
9505        assert_v1_to_v2_error(
9506            v1::AgentRequest::WaitForTerminalExitRequest(v1::WaitForTerminalExitRequest::new(
9507                "sess", "term",
9508            )),
9509            "v1 AgentRequest variant `terminal/wait_for_exit` cannot be represented in v2",
9510        );
9511        assert_v1_to_v2_error(
9512            v1::AgentRequest::KillTerminalRequest(v1::KillTerminalRequest::new("sess", "term")),
9513            "v1 AgentRequest variant `terminal/kill` cannot be represented in v2",
9514        );
9515
9516        assert_v1_to_v2_error(
9517            v1::ClientResponse::WriteTextFileResponse(v1::WriteTextFileResponse::new()),
9518            "v1 ClientResponse variant `fs/write_text_file` cannot be represented in v2",
9519        );
9520        assert_v1_to_v2_error(
9521            v1::ClientResponse::ReadTextFileResponse(v1::ReadTextFileResponse::new("contents")),
9522            "v1 ClientResponse variant `fs/read_text_file` cannot be represented in v2",
9523        );
9524        assert_v1_to_v2_error(
9525            v1::ClientResponse::CreateTerminalResponse(v1::CreateTerminalResponse::new("term")),
9526            "v1 ClientResponse variant `terminal/create` cannot be represented in v2",
9527        );
9528        assert_v1_to_v2_error(
9529            v1::ClientResponse::TerminalOutputResponse(v1::TerminalOutputResponse::new("", false)),
9530            "v1 ClientResponse variant `terminal/output` cannot be represented in v2",
9531        );
9532        assert_v1_to_v2_error(
9533            v1::ClientResponse::ReleaseTerminalResponse(v1::ReleaseTerminalResponse::new()),
9534            "v1 ClientResponse variant `terminal/release` cannot be represented in v2",
9535        );
9536        assert_v1_to_v2_error(
9537            v1::ClientResponse::WaitForTerminalExitResponse(v1::WaitForTerminalExitResponse::new(
9538                v1::TerminalExitStatus::new(),
9539            )),
9540            "v1 ClientResponse variant `terminal/wait_for_exit` cannot be represented in v2",
9541        );
9542        assert_v1_to_v2_error(
9543            v1::ClientResponse::KillTerminalResponse(v1::KillTerminalResponse::new()),
9544            "v1 ClientResponse variant `terminal/kill` cannot be represented in v2",
9545        );
9546    }
9547
9548    #[test]
9549    fn v1_terminal_tool_call_content_does_not_convert_to_v2() {
9550        assert_v1_to_v2_error(
9551            v1::ToolCallContent::Terminal(v1::Terminal::new("term")),
9552            "v1 ToolCallContent variant `terminal` cannot be represented in v2",
9553        );
9554    }
9555
9556    #[test]
9557    fn v1_mcp_sse_transport_does_not_convert_to_v2() {
9558        assert_v1_to_v2_error(
9559            v1::McpServer::Sse(v1::McpServerSse::new("events", "https://example.com/sse")),
9560            "v1 McpServer variant `sse` cannot be represented in v2",
9561        );
9562    }
9563
9564    #[test]
9565    fn v2_unknown_mcp_transport_does_not_convert_to_v1() {
9566        assert_v2_to_v1_error(
9567            v2::McpServer::Other(v2::OtherMcpServer::new("websocket", BTreeMap::default())),
9568            "v2 McpServer variant `websocket` cannot be represented in v1",
9569        );
9570    }
9571
9572    #[test]
9573    fn round_trips_new_session_request_with_mcp_variants() {
9574        let request = v1::NewSessionRequest::new("/workspace").mcp_servers(vec![
9575            v1::McpServer::Stdio(v1::McpServerStdio::new("local", "/usr/bin/mcp")),
9576            v1::McpServer::Http(v1::McpServerHttp::new("remote", "https://example.com")),
9577        ]);
9578
9579        assert_v1_round_trip::<v1::NewSessionRequest, v2::NewSessionRequest>(request.clone());
9580
9581        let v2_request: v2::NewSessionRequest = v1_to_v2(request).expect("v1 -> v2 conversion");
9582        assert_eq!(
9583            serde_json::to_value(&v2_request).expect("v2 serialize"),
9584            serde_json::json!({
9585                "cwd": "/workspace",
9586                "mcpServers": [
9587                    {
9588                        "type": "stdio",
9589                        "name": "local",
9590                        "command": "/usr/bin/mcp"
9591                    },
9592                    {
9593                        "type": "http",
9594                        "name": "remote",
9595                        "url": "https://example.com"
9596                    }
9597                ]
9598            })
9599        );
9600    }
9601
9602    #[test]
9603    fn round_trips_prompt_request_with_content_variants() {
9604        let prompt = vec![
9605            v1::ContentBlock::Text(v1::TextContent::new("hello")),
9606            v1::ContentBlock::Image(v1::ImageContent::new("data", "image/png")),
9607            v1::ContentBlock::ResourceLink(v1::ResourceLink::new("file.txt", "file:///file.txt")),
9608        ];
9609        let request = v1::PromptRequest::new("sess_1", prompt);
9610        assert_v1_round_trip::<v1::PromptRequest, v2::PromptRequest>(request.clone());
9611        assert_json_eq_after_v1_to_v2::<v1::PromptRequest, v2::PromptRequest>(request);
9612    }
9613
9614    #[cfg(feature = "unstable_elicitation")]
9615    #[test]
9616    fn round_trips_elicitation_property_schema_unknown_type() {
9617        let v1_schema = v1::ElicitationSchema::new().property(
9618            "location",
9619            v1::ElicitationPropertySchema::Other(v1::OtherElicitationPropertySchema::new(
9620                "_location",
9621                std::collections::BTreeMap::from([(
9622                    "precision".to_string(),
9623                    serde_json::json!("city"),
9624                )]),
9625            )),
9626            false,
9627        );
9628
9629        assert_v1_round_trip::<v1::ElicitationSchema, v2::ElicitationSchema>(v1_schema.clone());
9630        assert_json_eq_after_v1_to_v2::<v1::ElicitationSchema, v2::ElicitationSchema>(v1_schema);
9631
9632        let v2_schema = v2::ElicitationSchema::new().property(
9633            "location",
9634            v2::ElicitationPropertySchema::Other(v2::OtherElicitationPropertySchema::new(
9635                "_location",
9636                std::collections::BTreeMap::from([(
9637                    "precision".to_string(),
9638                    serde_json::json!("city"),
9639                )]),
9640            )),
9641            false,
9642        );
9643
9644        assert_v2_round_trip::<v2::ElicitationSchema, v1::ElicitationSchema>(v2_schema);
9645    }
9646
9647    #[cfg(feature = "unstable_elicitation")]
9648    #[test]
9649    fn round_trips_multi_select_items_unknown_type() {
9650        let v1_items = v1::MultiSelectItems::Other(v1::OtherMultiSelectItems::new(
9651            "_token",
9652            std::collections::BTreeMap::from([
9653                ("format".to_string(), serde_json::json!("workspace")),
9654                (
9655                    "anyOf".to_string(),
9656                    serde_json::json!([{ "const": "repo", "title": "Repository" }]),
9657                ),
9658            ]),
9659        ));
9660
9661        assert_v1_round_trip::<v1::MultiSelectItems, v2::MultiSelectItems>(v1_items.clone());
9662        assert_json_eq_after_v1_to_v2::<v1::MultiSelectItems, v2::MultiSelectItems>(v1_items);
9663
9664        let v2_items = v2::MultiSelectItems::Other(v2::OtherMultiSelectItems::new(
9665            "_token",
9666            std::collections::BTreeMap::from([
9667                ("format".to_string(), serde_json::json!("workspace")),
9668                (
9669                    "anyOf".to_string(),
9670                    serde_json::json!([{ "const": "repo", "title": "Repository" }]),
9671                ),
9672            ]),
9673        ));
9674
9675        assert_v2_round_trip::<v2::MultiSelectItems, v1::MultiSelectItems>(v2_items);
9676    }
9677
9678    #[cfg(feature = "unstable_elicitation")]
9679    #[test]
9680    fn round_trips_elicitation_mode_unknown_type() {
9681        let v1_request = v1::CreateElicitationRequest::new(
9682            v1::OtherElicitationMode::new(
9683                "_browser",
9684                v1::ElicitationRequestScope::new(v1::RequestId::Number(42)),
9685                std::collections::BTreeMap::from([(
9686                    "target".to_string(),
9687                    serde_json::json!("login"),
9688                )]),
9689            ),
9690            "Open a browser window",
9691        );
9692
9693        assert_v1_round_trip::<v1::CreateElicitationRequest, v2::CreateElicitationRequest>(
9694            v1_request.clone(),
9695        );
9696        assert_json_eq_after_v1_to_v2::<v1::CreateElicitationRequest, v2::CreateElicitationRequest>(
9697            v1_request,
9698        );
9699
9700        let v2_request = v2::CreateElicitationRequest::new(
9701            v2::OtherElicitationMode::new(
9702                "_browser",
9703                v2::ElicitationRequestScope::new(v2::RequestId::Number(42)),
9704                std::collections::BTreeMap::from([(
9705                    "target".to_string(),
9706                    serde_json::json!("login"),
9707                )]),
9708            ),
9709            "Open a browser window",
9710        );
9711
9712        assert_v2_round_trip::<v2::CreateElicitationRequest, v1::CreateElicitationRequest>(
9713            v2_request,
9714        );
9715    }
9716
9717    #[cfg(feature = "unstable_elicitation")]
9718    #[test]
9719    fn round_trips_elicitation_action_unknown_type() {
9720        let v1_response = v1::CreateElicitationResponse::new(v1::OtherElicitationAction::new(
9721            "_defer",
9722            std::collections::BTreeMap::from([
9723                ("reason".to_string(), serde_json::json!("waiting")),
9724                ("retryAfterMs".to_string(), serde_json::json!(1000)),
9725            ]),
9726        ));
9727
9728        assert_v1_round_trip::<v1::CreateElicitationResponse, v2::CreateElicitationResponse>(
9729            v1_response.clone(),
9730        );
9731        assert_json_eq_after_v1_to_v2::<v1::CreateElicitationResponse, v2::CreateElicitationResponse>(
9732            v1_response,
9733        );
9734
9735        let v2_response = v2::CreateElicitationResponse::new(v2::OtherElicitationAction::new(
9736            "_defer",
9737            std::collections::BTreeMap::from([
9738                ("reason".to_string(), serde_json::json!("waiting")),
9739                ("retryAfterMs".to_string(), serde_json::json!(1000)),
9740            ]),
9741        ));
9742
9743        assert_v2_round_trip::<v2::CreateElicitationResponse, v1::CreateElicitationResponse>(
9744            v2_response,
9745        );
9746    }
9747
9748    #[test]
9749    fn prompt_responses_do_not_convert_across_v1_v2_lifecycle_boundary() {
9750        assert_v2_to_v1_error(
9751            v2::PromptResponse::new(),
9752            "v2 PromptResponse cannot be represented in v1 because v2 reports completion with state_update session updates",
9753        );
9754        assert_v1_to_v2_error(
9755            v1::PromptResponse::new(v1::StopReason::EndTurn),
9756            "v1 PromptResponse cannot be represented in v2 by itself because v2 reports completion with state_update session updates",
9757        );
9758    }
9759
9760    #[test]
9761    fn v1_tool_call_converts_to_v2_upsert_with_diff_and_locations() {
9762        let tool_call = v1::ToolCall::new("tc_1", "editing files")
9763            .kind(v1::ToolKind::Edit)
9764            .status(v1::ToolCallStatus::InProgress)
9765            .content(vec![v1::ToolCallContent::Diff(
9766                v1::Diff::new("/path", "new contents").old_text("old contents"),
9767            )])
9768            .locations(vec![v1::ToolCallLocation::new("/path").line(42)])
9769            .raw_input(serde_json::json!({"foo": "bar"}))
9770            .raw_output(serde_json::json!({"ok": true}));
9771
9772        let converted: v2::ToolCallUpdate = v1_to_v2(tool_call).expect("v1 -> v2 conversion");
9773        assert_eq!(
9774            serde_json::to_value(&converted).expect("v2 serialize"),
9775            serde_json::json!({
9776                "toolCallId": "tc_1",
9777                "title": "editing files",
9778                "kind": "edit",
9779                "status": "in_progress",
9780                "content": [
9781                    {
9782                        "type": "diff",
9783                        "changes": [
9784                            {
9785                                "operation": "modify",
9786                                "path": "/path",
9787                                "fileType": "text"
9788                            }
9789                        ],
9790                        "patch": {
9791                            "format": "git_patch",
9792                            "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"
9793                        }
9794                    }
9795                ],
9796                "locations": [
9797                    {
9798                        "path": "/path",
9799                        "line": 42
9800                    }
9801                ],
9802                "rawInput": {
9803                    "foo": "bar"
9804                },
9805                "rawOutput": {
9806                    "ok": true
9807                }
9808            })
9809        );
9810
9811        let back: v1::ToolCallUpdate = v2_to_v1(converted).expect("v2 -> v1 conversion");
9812        assert_eq!(back.tool_call_id.0.as_ref(), "tc_1");
9813        assert_eq!(back.fields.title.as_deref(), Some("editing files"));
9814        assert_eq!(back.fields.kind, Some(v1::ToolKind::Edit));
9815        assert_eq!(back.fields.status, Some(v1::ToolCallStatus::InProgress));
9816        assert_eq!(back.fields.content.as_ref().map(Vec::len), Some(0));
9817        assert_eq!(back.fields.locations.as_ref().map(Vec::len), Some(1));
9818        assert_eq!(
9819            back.fields.raw_input,
9820            Some(serde_json::json!({"foo": "bar"}))
9821        );
9822        assert_eq!(
9823            back.fields.raw_output,
9824            Some(serde_json::json!({"ok": true}))
9825        );
9826    }
9827
9828    #[test]
9829    fn v1_tool_call_update_round_trips_through_v2_tool_call_update_upsert() {
9830        let update = v1::ToolCallUpdate::new(
9831            "tc",
9832            v1::ToolCallUpdateFields::new()
9833                .status(v1::ToolCallStatus::Completed)
9834                .content(Vec::new()),
9835        );
9836
9837        assert_v1_round_trip::<v1::ToolCallUpdate, v2::ToolCallUpdate>(update.clone());
9838        assert_json_eq_after_v1_to_v2::<v1::ToolCallUpdate, v2::ToolCallUpdate>(update);
9839    }
9840
9841    #[test]
9842    fn v2_entity_meta_null_does_not_convert_to_v1() {
9843        assert_v2_to_v1_error(
9844            v2::SessionInfoUpdate::new().meta(None::<v2::Meta>),
9845            "v2 SessionInfoUpdate with null _meta cannot be represented in v1",
9846        );
9847        assert_v2_to_v1_error(
9848            v2::ToolCallUpdate::new("tc").meta(None::<v2::Meta>),
9849            "v2 ToolCallUpdate with null _meta cannot be represented in v1",
9850        );
9851    }
9852
9853    #[test]
9854    fn round_trips_session_notification_for_unchanged_update_kinds() {
9855        fn content_chunk(text: &str, message_id: &str) -> v1::ContentChunk {
9856            let chunk = v1::ContentChunk::new(v1::ContentBlock::Text(v1::TextContent::new(text)));
9857            chunk.message_id(message_id)
9858        }
9859
9860        let cases: Vec<v1::SessionUpdate> = vec![
9861            v1::SessionUpdate::UserMessageChunk(content_chunk("u", "msg_user")),
9862            v1::SessionUpdate::AgentMessageChunk(content_chunk("a", "msg_agent")),
9863            v1::SessionUpdate::AgentThoughtChunk(content_chunk("t", "msg_thought")),
9864            v1::SessionUpdate::SessionInfoUpdate(v1::SessionInfoUpdate::new().title("hi")),
9865            v1::SessionUpdate::UsageUpdate(
9866                v1::UsageUpdate::new(53_000, 200_000).cost(v1::Cost::new(0.045, "USD")),
9867            ),
9868        ];
9869        for update in cases {
9870            let notification = v1::SessionNotification::new("sess", update);
9871            let original_json = serde_json::to_value(&notification).expect("v1 serialize");
9872            let as_v2: v2::UpdateSessionNotification =
9873                v1_to_v2(notification.clone()).expect("v1 -> v2 conversion");
9874            let v2_json = serde_json::to_value(&as_v2).expect("v2 serialize");
9875            assert_eq!(
9876                original_json, v2_json,
9877                "JSON shape diverged after v1 -> v2 conversion"
9878            );
9879
9880            let back = v2_to_v1_many(as_v2).expect("v2 -> v1 conversion");
9881            assert_eq!(back, vec![notification]);
9882            let back_json = serde_json::to_value(&back[0]).expect("v1 serialize after round trip");
9883            assert_eq!(
9884                original_json, back_json,
9885                "JSON shape diverged after v2 -> v1 conversion"
9886            );
9887        }
9888    }
9889
9890    #[test]
9891    fn v1_tool_call_session_updates_convert_to_unified_v2_tool_call_update() {
9892        let create = v1::SessionNotification::new(
9893            "sess",
9894            v1::SessionUpdate::ToolCall(v1::ToolCall::new("tc", "title")),
9895        );
9896        let create_v2: v2::UpdateSessionNotification =
9897            v1_to_v2(create).expect("v1 -> v2 conversion");
9898        assert!(matches!(
9899            create_v2.update,
9900            v2::SessionUpdate::ToolCallUpdate(_)
9901        ));
9902        assert_eq!(
9903            serde_json::to_value(&create_v2).expect("v2 serialize"),
9904            serde_json::json!({
9905                "sessionId": "sess",
9906                "update": {
9907                    "sessionUpdate": "tool_call_update",
9908                    "toolCallId": "tc",
9909                    "title": "title"
9910                }
9911            })
9912        );
9913
9914        let update = v1::SessionNotification::new(
9915            "sess",
9916            v1::SessionUpdate::ToolCallUpdate(v1::ToolCallUpdate::new(
9917                "tc",
9918                v1::ToolCallUpdateFields::new().status(v1::ToolCallStatus::Completed),
9919            )),
9920        );
9921        let update_v2: v2::UpdateSessionNotification =
9922            v1_to_v2(update).expect("v1 -> v2 conversion");
9923        assert!(matches!(
9924            update_v2.update,
9925            v2::SessionUpdate::ToolCallUpdate(_)
9926        ));
9927        assert_eq!(
9928            serde_json::to_value(&update_v2).expect("v2 serialize"),
9929            serde_json::json!({
9930                "sessionId": "sess",
9931                "update": {
9932                    "sessionUpdate": "tool_call_update",
9933                    "toolCallId": "tc",
9934                    "status": "completed"
9935                }
9936            })
9937        );
9938    }
9939
9940    #[test]
9941    fn v2_full_messages_convert_to_v1_message_chunks() {
9942        let mut meta = v2::Meta::new();
9943        meta.insert("source".to_string(), serde_json::json!("full"));
9944
9945        let chunks = v2_to_v1_many(v2::SessionUpdate::UserMessage(
9946            v2::UserMessage::new("msg_user")
9947                .content(vec![
9948                    v2::ContentBlock::Text(v2::TextContent::new("hello")),
9949                    v2::ContentBlock::Text(v2::TextContent::new("world")),
9950                ])
9951                .meta(meta.clone()),
9952        ))
9953        .expect("v2 -> v1 conversion");
9954        assert_eq!(
9955            chunks,
9956            vec![
9957                v1::SessionUpdate::UserMessageChunk(
9958                    v1::ContentChunk::new(v1::ContentBlock::Text(v1::TextContent::new("hello")))
9959                        .message_id("msg_user")
9960                        .meta(meta.clone())
9961                ),
9962                v1::SessionUpdate::UserMessageChunk(
9963                    v1::ContentChunk::new(v1::ContentBlock::Text(v1::TextContent::new("world")))
9964                        .message_id("msg_user")
9965                        .meta(meta)
9966                ),
9967            ]
9968        );
9969
9970        assert_eq!(
9971            v2_to_v1_many(v2::SessionUpdate::AgentMessage(
9972                v2::AgentMessage::new("msg_agent")
9973                    .content(vec![v2::ContentBlock::Text(v2::TextContent::new("hello"))])
9974            ))
9975            .expect("v2 -> v1 conversion"),
9976            vec![v1::SessionUpdate::AgentMessageChunk(
9977                v1::ContentChunk::new(v1::ContentBlock::Text(v1::TextContent::new("hello")))
9978                    .message_id("msg_agent")
9979            )]
9980        );
9981
9982        assert_eq!(
9983            v2_to_v1_many(v2::SessionUpdate::AgentThought(
9984                v2::AgentThought::new("msg_thought").content(vec![v2::ContentBlock::Text(
9985                    v2::TextContent::new("thinking")
9986                )])
9987            ))
9988            .expect("v2 -> v1 conversion"),
9989            vec![v1::SessionUpdate::AgentThoughtChunk(
9990                v1::ContentChunk::new(v1::ContentBlock::Text(v1::TextContent::new("thinking")))
9991                    .message_id("msg_thought")
9992            )]
9993        );
9994    }
9995
9996    #[test]
9997    fn v2_full_message_session_notification_fans_out_to_v1_chunk_notifications() {
9998        let notification = v2::UpdateSessionNotification::new(
9999            "sess",
10000            v2::SessionUpdate::AgentMessage(v2::AgentMessage::new("msg_agent").content(vec![
10001                v2::ContentBlock::Text(v2::TextContent::new("hello")),
10002                v2::ContentBlock::Text(v2::TextContent::new("world")),
10003            ])),
10004        );
10005
10006        let notifications = v2_to_v1_many(notification).expect("v2 -> v1 conversion");
10007        assert_eq!(
10008            notifications,
10009            vec![
10010                v1::SessionNotification::new(
10011                    "sess",
10012                    v1::SessionUpdate::AgentMessageChunk(
10013                        v1::ContentChunk::new(v1::ContentBlock::Text(v1::TextContent::new(
10014                            "hello"
10015                        )))
10016                        .message_id("msg_agent")
10017                    )
10018                ),
10019                v1::SessionNotification::new(
10020                    "sess",
10021                    v1::SessionUpdate::AgentMessageChunk(
10022                        v1::ContentChunk::new(v1::ContentBlock::Text(v1::TextContent::new(
10023                            "world"
10024                        )))
10025                        .message_id("msg_agent")
10026                    )
10027                ),
10028            ]
10029        );
10030    }
10031
10032    #[test]
10033    fn v2_json_rpc_agent_notification_fans_out_to_v1_chunk_notifications() {
10034        let message = v2::JsonRpcMessage::wrap(v2::Notification {
10035            method: "session/update".into(),
10036            params: Some(v2::AgentNotification::UpdateSessionNotification(Box::new(
10037                v2::UpdateSessionNotification::new(
10038                    "sess",
10039                    v2::SessionUpdate::AgentMessage(v2::AgentMessage::new("msg_agent").content(
10040                        vec![
10041                            v2::ContentBlock::Text(v2::TextContent::new("hello")),
10042                            v2::ContentBlock::Text(v2::TextContent::new("world")),
10043                        ],
10044                    )),
10045                ),
10046            ))),
10047        });
10048
10049        let messages = v2_to_v1_many(message).expect("v2 -> v1 conversion");
10050        let json = messages
10051            .into_iter()
10052            .map(|message| serde_json::to_value(message).expect("serialize v1 message"))
10053            .collect::<Vec<_>>();
10054        assert_eq!(
10055            json,
10056            vec![
10057                serde_json::json!({
10058                    "jsonrpc": "2.0",
10059                    "method": "session/update",
10060                    "params": {
10061                        "sessionId": "sess",
10062                        "update": {
10063                            "sessionUpdate": "agent_message_chunk",
10064                            "content": {
10065                                "type": "text",
10066                                "text": "hello"
10067                            },
10068                            "messageId": "msg_agent"
10069                        }
10070                    }
10071                }),
10072                serde_json::json!({
10073                    "jsonrpc": "2.0",
10074                    "method": "session/update",
10075                    "params": {
10076                        "sessionId": "sess",
10077                        "update": {
10078                            "sessionUpdate": "agent_message_chunk",
10079                            "content": {
10080                                "type": "text",
10081                                "text": "world"
10082                            },
10083                            "messageId": "msg_agent"
10084                        }
10085                    }
10086                }),
10087            ]
10088        );
10089    }
10090
10091    #[test]
10092    fn v2_message_patches_and_clears_do_not_convert_to_v1_chunks() {
10093        assert_v2_to_v1_many_error(
10094            v2::SessionUpdate::AgentMessage(v2::AgentMessage::new("msg_agent")),
10095            "v2 SessionUpdate variant `agent_message` without content cannot be represented in v1 chunks",
10096        );
10097
10098        assert_v2_to_v1_many_error(
10099            v2::SessionUpdate::AgentMessage(
10100                v2::AgentMessage::new("msg_agent").content(None::<Vec<v2::ContentBlock>>),
10101            ),
10102            "v2 SessionUpdate variant `agent_message` with null content cannot be represented in v1 chunks",
10103        );
10104
10105        assert_v2_to_v1_many_error(
10106            v2::SessionUpdate::AgentMessage(
10107                v2::AgentMessage::new("msg_agent").content(Vec::<v2::ContentBlock>::new()),
10108            ),
10109            "v2 SessionUpdate variant `agent_message` with empty content cannot be represented in v1 chunks",
10110        );
10111
10112        assert_v2_to_v1_many_error(
10113            v2::SessionUpdate::AgentMessage(
10114                v2::AgentMessage::new("msg_agent")
10115                    .content(vec![v2::ContentBlock::Text(v2::TextContent::new("hello"))])
10116                    .meta(None::<v2::Meta>),
10117            ),
10118            "v2 SessionUpdate variant `agent_message` with null _meta cannot be represented in v1 chunks",
10119        );
10120    }
10121
10122    #[test]
10123    fn v2_tool_call_content_chunk_does_not_convert_to_v1_replacement_update() {
10124        assert_v2_to_v1_many_error(
10125            v2::SessionUpdate::ToolCallContentChunk(v2::ToolCallContentChunk::new(
10126                "tc_1",
10127                v2::ContentBlock::Text(v2::TextContent::new("partial output")),
10128            )),
10129            "v2 SessionUpdate variant `tool_call_content_chunk` cannot be represented in v1 because v1 tool-call content updates replace content instead of appending",
10130        );
10131    }
10132
10133    #[test]
10134    fn v1_content_chunk_without_message_id_does_not_convert_to_v2() {
10135        assert_v1_to_v2_error(
10136            v1::ContentChunk::new(v1::ContentBlock::Text(v1::TextContent::new("missing"))),
10137            "v1 ContentChunk without messageId cannot be represented in v2",
10138        );
10139    }
10140
10141    #[test]
10142    fn v1_plan_session_update_converts_to_v2_item_plan_update() {
10143        let update = v1::SessionUpdate::Plan(v1::Plan::new(vec![v1::PlanEntry::new(
10144            "step",
10145            v1::PlanEntryPriority::High,
10146            v1::PlanEntryStatus::InProgress,
10147        )]));
10148
10149        let as_v2: v2::SessionUpdate = v1_to_v2(update.clone()).unwrap();
10150        assert_eq!(
10151            serde_json::to_value(&as_v2).unwrap(),
10152            serde_json::json!({
10153                "sessionUpdate": "plan_update",
10154                "plan": {
10155                    "type": "items",
10156                    "planId": LEGACY_V1_PLAN_ID,
10157                    "entries": [
10158                        {
10159                            "content": "step",
10160                            "priority": "high",
10161                            "status": "in_progress"
10162                        }
10163                    ]
10164                }
10165            })
10166        );
10167
10168        let back = v2_to_v1_many(as_v2).unwrap();
10169        #[cfg(not(feature = "unstable_plan_operations"))]
10170        assert_eq!(back, vec![update]);
10171        #[cfg(feature = "unstable_plan_operations")]
10172        assert!(matches!(
10173            back.as_slice(),
10174            [v1::SessionUpdate::PlanUpdate(_)]
10175        ));
10176    }
10177
10178    #[test]
10179    fn unknown_v2_session_update_does_not_convert_to_v1() {
10180        let update = v2::SessionUpdate::Other(v2::OtherSessionUpdate::new(
10181            "_status_badge",
10182            std::collections::BTreeMap::new(),
10183        ));
10184
10185        assert_v2_to_v1_many_error(
10186            update,
10187            "v2 SessionUpdate variant `_status_badge` cannot be represented in v1",
10188        );
10189    }
10190
10191    #[test]
10192    fn v2_state_update_does_not_convert_to_v1() {
10193        assert_v2_to_v1_many_error(
10194            v2::SessionUpdate::StateUpdate(v2::StateUpdate::Idle(
10195                v2::IdleStateUpdate::new().stop_reason(v2::StopReason::EndTurn),
10196            )),
10197            "v2 SessionUpdate variant `state_update` cannot be represented in v1 because v1 reports completion in the session/prompt response",
10198        );
10199    }
10200
10201    #[test]
10202    fn v1_current_mode_update_does_not_convert_to_v2() {
10203        assert_v1_to_v2_error(
10204            v1::SessionUpdate::CurrentModeUpdate(v1::CurrentModeUpdate::new("ask")),
10205            "v1 SessionUpdate variant `current_mode_update` cannot be represented in v2",
10206        );
10207    }
10208
10209    #[test]
10210    fn v1_session_mode_methods_do_not_convert_to_v2() {
10211        assert_v1_to_v2_error(
10212            v1::ClientRequest::SetSessionModeRequest(v1::SetSessionModeRequest::new("sess", "ask")),
10213            "v1 ClientRequest variant `session/set_mode` cannot be represented in v2",
10214        );
10215        assert_v1_to_v2_error(
10216            v1::AgentResponse::SetSessionModeResponse(v1::SetSessionModeResponse::new()),
10217            "v1 AgentResponse variant `session/set_mode` cannot be represented in v2",
10218        );
10219    }
10220
10221    #[test]
10222    fn v1_session_response_modes_fall_back_to_none_in_v2() {
10223        let response = v1::NewSessionResponse::new("sess").modes(v1::SessionModeState::new(
10224            "ask",
10225            vec![v1::SessionMode::new("ask", "Ask")],
10226        ));
10227
10228        let as_v2: v2::NewSessionResponse = v1_to_v2(response).unwrap();
10229        let back_to_v1: v1::NewSessionResponse = v2_to_v1(as_v2).unwrap();
10230
10231        assert!(back_to_v1.modes.is_none());
10232    }
10233
10234    #[test]
10235    fn v1_session_response_missing_config_options_becomes_empty_v2_vec() {
10236        let new_response: v2::NewSessionResponse =
10237            v1_to_v2(v1::NewSessionResponse::new("sess")).unwrap();
10238        assert!(new_response.config_options.is_empty());
10239
10240        let load_response: v2::ResumeSessionResponse =
10241            v1_to_v2(v1::LoadSessionResponse::new()).unwrap();
10242        assert!(load_response.config_options.is_empty());
10243
10244        let resume_response: v2::ResumeSessionResponse =
10245            v1_to_v2(v1::ResumeSessionResponse::new()).unwrap();
10246        assert!(resume_response.config_options.is_empty());
10247
10248        #[cfg(feature = "unstable_session_fork")]
10249        {
10250            let fork_response: v2::ForkSessionResponse =
10251                v1_to_v2(v1::ForkSessionResponse::new("fork")).unwrap();
10252            assert!(fork_response.config_options.is_empty());
10253        }
10254    }
10255
10256    #[test]
10257    fn v2_resume_replay_from_start_maps_to_v1_load_request() {
10258        let v1_load = v1::ClientRequest::LoadSessionRequest(v1::LoadSessionRequest::new(
10259            "sess",
10260            "/workspace/project",
10261        ));
10262        let v2_request: v2::ClientRequest = v1_to_v2(v1_load).unwrap();
10263        let v2::ClientRequest::ResumeSessionRequest(resume) = v2_request else {
10264            panic!("v1 session/load should convert to v2 session/resume");
10265        };
10266        assert!(matches!(resume.replay_from, Some(v2::ReplayFrom::Start(_))));
10267
10268        let v1_request: v1::ClientRequest =
10269            v2_to_v1(v2::ClientRequest::ResumeSessionRequest(resume)).unwrap();
10270        assert!(matches!(
10271            v1_request,
10272            v1::ClientRequest::LoadSessionRequest(_)
10273        ));
10274    }
10275
10276    #[test]
10277    fn v2_resume_without_replay_maps_to_v1_resume_request() {
10278        let v2_request = v2::ClientRequest::ResumeSessionRequest(Box::new(
10279            v2::ResumeSessionRequest::new("sess", "/workspace/project"),
10280        ));
10281
10282        let v1_request: v1::ClientRequest = v2_to_v1(v2_request).unwrap();
10283        assert!(matches!(
10284            v1_request,
10285            v1::ClientRequest::ResumeSessionRequest(_)
10286        ));
10287    }
10288
10289    #[test]
10290    fn v2_session_response_converts_to_v1_without_mode_state() {
10291        let response: v1::NewSessionResponse =
10292            v2_to_v1(v2::NewSessionResponse::new("sess")).unwrap();
10293
10294        assert!(response.modes.is_none());
10295        assert!(matches!(
10296            response.config_options,
10297            Some(config_options) if config_options.is_empty()
10298        ));
10299    }
10300
10301    #[test]
10302    fn v2_tool_call_update_conversion_matches_v1_default_on_error_fields() {
10303        let update = v2::ToolCallUpdate::new("tc")
10304            .kind(v2::ToolKind::Unknown("_future_kind".to_string()))
10305            .status(v2::ToolCallStatus::Other("_paused".to_string()))
10306            .content(vec![
10307                v2::ToolCallContent::Other(v2::OtherToolCallContent::new(
10308                    "_chart",
10309                    BTreeMap::default(),
10310                )),
10311                v2::ToolCallContent::Diff(v2::Diff::patch(
10312                    "diff --git /tmp/file.txt /tmp/file.txt\n",
10313                    vec![v2::DiffChange::modify("/tmp/file.txt")],
10314                )),
10315            ]);
10316
10317        let converted: v1::ToolCallUpdate = v2_to_v1(update).unwrap();
10318
10319        assert_eq!(converted.fields.kind, None);
10320        assert_eq!(converted.fields.status, None);
10321        assert_eq!(converted.fields.content, Some(vec![]));
10322    }
10323
10324    #[test]
10325    fn v2_collection_conversion_skips_items_like_v1_vec_skip_error() {
10326        let response = v2::InitializeResponse::new(
10327            ProtocolVersion::V2,
10328            v2::Implementation::new("test-agent", "2.0.0"),
10329        )
10330        .capabilities(v2::AgentCapabilities::new().session(v2::SessionCapabilities::new()))
10331        .auth_methods(vec![
10332            v2::AuthMethod::Other(v2::OtherAuthMethod::new(
10333                "_oauth",
10334                "oauth",
10335                "OAuth",
10336                BTreeMap::default(),
10337            )),
10338            v2::AuthMethod::Agent(v2::AuthMethodAgent::new("agent", "Agent")),
10339        ]);
10340        let converted: v1::InitializeResponse = v2_to_v1(response).unwrap();
10341        assert_eq!(converted.auth_methods.len(), 1);
10342        assert!(matches!(
10343            converted.auth_methods[0],
10344            v1::AuthMethod::Agent(_)
10345        ));
10346
10347        let config_update = v2::ConfigOptionUpdate::new(vec![
10348            v2::SessionConfigOption::select(
10349                "mode",
10350                "Mode",
10351                "ask",
10352                vec![v2::SessionConfigSelectOption::new("ask", "Ask")],
10353            ),
10354            v2::SessionConfigOption::new(
10355                "future",
10356                "Future",
10357                v2::SessionConfigKind::Other(v2::OtherSessionConfigKind::new(
10358                    "_slider",
10359                    BTreeMap::default(),
10360                )),
10361            ),
10362        ]);
10363        let converted: v1::ConfigOptionUpdate = v2_to_v1(config_update).unwrap();
10364        assert_eq!(converted.config_options.len(), 1);
10365        assert_eq!(converted.config_options[0].id.0.as_ref(), "mode");
10366    }
10367
10368    #[test]
10369    fn v2_default_on_error_fields_drop_unrepresentable_nested_values() {
10370        let command = v2::AvailableCommand::new("review", "Review changes").input(
10371            v2::AvailableCommandInput::Other(v2::OtherAvailableCommandInput::new(
10372                "_choices",
10373                BTreeMap::default(),
10374            )),
10375        );
10376        let converted: v1::AvailableCommandsUpdate =
10377            v2_to_v1(v2::AvailableCommandsUpdate::new(vec![command])).unwrap();
10378
10379        assert_eq!(converted.available_commands.len(), 1);
10380        assert_eq!(converted.available_commands[0].input, None);
10381
10382        let content = v2::TextContent::new("hello").annotations(
10383            v2::Annotations::new()
10384                .audience(vec![v2::Role::Other("_critic".to_string()), v2::Role::User]),
10385        );
10386        let converted: v1::TextContent = v2_to_v1(content).unwrap();
10387
10388        assert_eq!(
10389            converted
10390                .annotations
10391                .and_then(|annotations| annotations.audience),
10392            Some(vec![v1::Role::User])
10393        );
10394    }
10395
10396    #[test]
10397    fn available_command_input_conversion_adds_v2_discriminator() {
10398        let input = v1::AvailableCommandInput::Unstructured(v1::UnstructuredCommandInput::new(
10399            "Describe changes",
10400        ));
10401
10402        let v2_input: v2::AvailableCommandInput = v1_to_v2(input.clone()).unwrap();
10403        assert_eq!(
10404            serde_json::to_value(&v2_input).unwrap(),
10405            serde_json::json!({
10406                "type": "text",
10407                "hint": "Describe changes"
10408            })
10409        );
10410
10411        let v1_input: v1::AvailableCommandInput = v2_to_v1(v2_input).unwrap();
10412        assert_eq!(v1_input, input);
10413        assert_eq!(
10414            serde_json::to_value(v1_input).unwrap(),
10415            serde_json::json!({
10416                "hint": "Describe changes"
10417            })
10418        );
10419    }
10420
10421    #[test]
10422    fn v2_plan_entries_skip_unrepresentable_items_inside_tolerant_vectors() {
10423        let update = v2::PlanUpdate::new(v2::PlanUpdateContent::items(
10424            "main",
10425            vec![
10426                v2::PlanEntry::new(
10427                    "keep",
10428                    v2::PlanEntryPriority::High,
10429                    v2::PlanEntryStatus::Pending,
10430                ),
10431                v2::PlanEntry::new(
10432                    "drop",
10433                    v2::PlanEntryPriority::Other("_critical".to_string()),
10434                    v2::PlanEntryStatus::Pending,
10435                ),
10436            ],
10437        ));
10438
10439        #[cfg(not(feature = "unstable_plan_operations"))]
10440        {
10441            let converted: v1::Plan = v2_to_v1(update).unwrap();
10442            assert_eq!(converted.entries.len(), 1);
10443            assert_eq!(converted.entries[0].content, "keep");
10444        }
10445
10446        #[cfg(feature = "unstable_plan_operations")]
10447        {
10448            let converted: v1::PlanUpdate = v2_to_v1(update).unwrap();
10449            let v1::PlanUpdateContent::Items(items) = converted.plan else {
10450                panic!("expected item plan update");
10451            };
10452            assert_eq!(items.entries.len(), 1);
10453            assert_eq!(items.entries[0].content, "keep");
10454        }
10455    }
10456
10457    #[test]
10458    fn v1_tool_call_update_conversion_skips_items_for_v2_vec_skip_error_fields() {
10459        let update = v1::ToolCallUpdate::new(
10460            "tc",
10461            v1::ToolCallUpdateFields::new().content(vec![
10462                v1::ToolCallContent::Terminal(v1::Terminal::new("term")),
10463                v1::ToolCallContent::Diff(v1::Diff::new("/tmp/file.txt", "new")),
10464            ]),
10465        );
10466
10467        let converted: v2::ToolCallUpdate = v1_to_v2(update).unwrap();
10468        assert_eq!(
10469            converted.content,
10470            crate::MaybeUndefined::Value(vec![v2::ToolCallContent::Diff(v2::Diff::patch(
10471                full_file_git_patch(&PathBuf::from("/tmp/file.txt"), None, "new"),
10472                vec![v2::DiffChange::add("/tmp/file.txt").file_type(v2::DiffFileType::Text)],
10473            ))])
10474        );
10475    }
10476
10477    #[test]
10478    fn v2_resource_link_icons_do_not_convert_to_v1() {
10479        assert_v2_to_v1_error(
10480            v2::ResourceLink::new("file.txt", "file:///file.txt")
10481                .icons(vec![v2::Icon::new("https://example.com/icon.png")]),
10482            "v2 ResourceLink.icons cannot be represented in v1",
10483        );
10484    }
10485
10486    #[test]
10487    fn unknown_v2_raw_fallbacks_do_not_convert_to_v1() {
10488        assert_v2_to_v1_error(
10489            v2::ContentBlock::Other(v2::OtherContentBlock::new(
10490                "_widget",
10491                std::collections::BTreeMap::new(),
10492            )),
10493            "v2 ContentBlock variant `_widget` cannot be represented in v1",
10494        );
10495        assert_v2_to_v1_error(
10496            v2::ToolCallContent::Other(v2::OtherToolCallContent::new(
10497                "_chart",
10498                std::collections::BTreeMap::new(),
10499            )),
10500            "v2 ToolCallContent variant `_chart` cannot be represented in v1",
10501        );
10502        assert_v2_to_v1_error(
10503            v2::AvailableCommandInput::Other(v2::OtherAvailableCommandInput::new(
10504                "_choices",
10505                std::collections::BTreeMap::new(),
10506            )),
10507            "v2 AvailableCommandInput variant `_choices` cannot be represented in v1",
10508        );
10509        assert_v2_to_v1_error(
10510            v2::RequestPermissionRequest::new("session-id", "Permission requested", Vec::new())
10511                .subject(v2::RequestPermissionSubject::Other(
10512                    v2::OtherRequestPermissionSubject::new(
10513                        "_review",
10514                        std::collections::BTreeMap::new(),
10515                    ),
10516                )),
10517            "v2 RequestPermissionSubject variant `_review` cannot be represented in v1",
10518        );
10519        assert_v2_to_v1_error(
10520            v2::RequestPermissionRequest::new("session-id", "Permission requested", Vec::new()),
10521            "v2 RequestPermissionRequest without `subject` cannot be represented in v1",
10522        );
10523        assert_v2_to_v1_error(
10524            v2::RequestPermissionOutcome::Other(v2::OtherRequestPermissionOutcome::new(
10525                "_defer",
10526                std::collections::BTreeMap::new(),
10527            )),
10528            "v2 RequestPermissionOutcome variant `_defer` cannot be represented in v1",
10529        );
10530        assert_v2_to_v1_error(
10531            v2::SessionConfigKind::Other(v2::OtherSessionConfigKind::new(
10532                "_slider",
10533                std::collections::BTreeMap::new(),
10534            )),
10535            "v2 SessionConfigKind variant `_slider` cannot be represented in v1",
10536        );
10537        assert_v2_to_v1_error(
10538            v2::AuthMethod::Other(v2::OtherAuthMethod::new(
10539                "_oauth",
10540                "oauth",
10541                "OAuth",
10542                std::collections::BTreeMap::new(),
10543            )),
10544            "v2 AuthMethod variant `_oauth` cannot be represented in v1",
10545        );
10546        assert_v2_to_v1_error(
10547            v2::PlanUpdate::new(v2::PlanUpdateContent::Other(
10548                v2::OtherPlanUpdateContent::new(
10549                    "_timeline",
10550                    "plan-1",
10551                    std::collections::BTreeMap::new(),
10552                ),
10553            )),
10554            "v2 PlanUpdateContent variant `_timeline` cannot be represented in v1",
10555        );
10556        #[cfg(feature = "unstable_nes")]
10557        assert_v2_to_v1_error(
10558            v2::NesSuggestion::Other(v2::OtherNesSuggestion::new(
10559                "_preview",
10560                "preview-1",
10561                std::collections::BTreeMap::new(),
10562            )),
10563            "v2 NesSuggestion variant `_preview` cannot be represented in v1",
10564        );
10565    }
10566
10567    #[test]
10568    fn round_trips_request_permission_outcomes() {
10569        let cancelled = v1::RequestPermissionResponse::new(v1::RequestPermissionOutcome::Cancelled);
10570        assert_v1_round_trip::<v1::RequestPermissionResponse, v2::RequestPermissionResponse>(
10571            cancelled,
10572        );
10573
10574        let selected = v1::RequestPermissionResponse::new(v1::RequestPermissionOutcome::Selected(
10575            v1::SelectedPermissionOutcome::new("opt_1"),
10576        ));
10577        assert_v1_round_trip::<v1::RequestPermissionResponse, v2::RequestPermissionResponse>(
10578            selected,
10579        );
10580    }
10581
10582    #[test]
10583    fn converts_v1_request_permission_request_with_required_v2_title() {
10584        let titled = v1::RequestPermissionRequest::new(
10585            "session-id",
10586            v1::ToolCallUpdate::new("call_1", v1::ToolCallUpdateFields::new().title("Read file")),
10587            Vec::new(),
10588        );
10589
10590        let converted: v2::RequestPermissionRequest = v1_to_v2(titled).unwrap();
10591        assert_eq!(converted.title, "Read file");
10592        let Some(v2::RequestPermissionSubject::ToolCall(subject)) = converted.subject else {
10593            panic!("expected tool-call permission subject");
10594        };
10595        assert_eq!(subject.tool_call.tool_call_id.to_string(), "call_1");
10596
10597        let fallback = v1::RequestPermissionRequest::new(
10598            "session-id",
10599            v1::ToolCallUpdate::new("call_2", v1::ToolCallUpdateFields::new()),
10600            Vec::new(),
10601        );
10602
10603        let converted: v2::RequestPermissionRequest = v1_to_v2(fallback).unwrap();
10604        assert_eq!(converted.title, "Permission requested");
10605        let Some(v2::RequestPermissionSubject::ToolCall(subject)) = converted.subject else {
10606            panic!("expected tool-call permission subject");
10607        };
10608        assert_eq!(subject.tool_call.tool_call_id.to_string(), "call_2");
10609    }
10610
10611    #[test]
10612    fn round_trips_error_with_data_payload() {
10613        let err = v1::Error::invalid_params().data(serde_json::json!({
10614            "reason": "missing field",
10615            "field": "sessionId",
10616        }));
10617        assert_v1_round_trip::<v1::Error, v2::Error>(err);
10618    }
10619
10620    #[test]
10621    fn round_trips_v2_value_back_through_v1() {
10622        // Same coverage but starting from v2, to exercise IntoV1 explicitly.
10623        let request = v2::PromptRequest::new(
10624            "sess_2",
10625            vec![v2::ContentBlock::Text(v2::TextContent::new("hi"))],
10626        );
10627        assert_v2_round_trip::<v2::PromptRequest, v1::PromptRequest>(request.clone());
10628        assert_json_eq_after_v2_to_v1::<v2::PromptRequest, v1::PromptRequest>(request);
10629    }
10630
10631    #[test]
10632    fn protocol_version_constants_remain_explicit() {
10633        assert_eq!(ProtocolVersion::V1.as_u16(), 1);
10634        assert_eq!(ProtocolVersion::V2.as_u16(), 2);
10635    }
10636
10637    /// `?` bubbles a [`ProtocolConversionError`] into a [`v1::Error`] without
10638    /// loss of message, mapped onto the internal-error code.
10639    #[test]
10640    fn protocol_conversion_error_maps_into_v1_error() {
10641        fn run() -> std::result::Result<(), v1::Error> {
10642            // Synthesize a conversion error so we don't have to wait for v2
10643            // to actually diverge before exercising the `?` path.
10644            Err(ProtocolConversionError::new("missing required field"))?;
10645            unreachable!();
10646        }
10647
10648        let err = run().unwrap_err();
10649        assert_eq!(err.code, v1::ErrorCode::InternalError);
10650        assert_eq!(
10651            err.data,
10652            Some(serde_json::Value::String(
10653                "missing required field".to_string()
10654            ))
10655        );
10656    }
10657
10658    /// Mirror of the v1 test for the v2 [`Error`] type.
10659    #[test]
10660    fn protocol_conversion_error_maps_into_v2_error() {
10661        fn run() -> std::result::Result<(), v2::Error> {
10662            Err(ProtocolConversionError::new("missing required field"))?;
10663            unreachable!();
10664        }
10665
10666        let err = run().unwrap_err();
10667        assert_eq!(err.code, v2::ErrorCode::InternalError);
10668        assert_eq!(
10669            err.data,
10670            Some(serde_json::Value::String(
10671                "missing required field".to_string()
10672            ))
10673        );
10674    }
10675}