Skip to main content

chio_cross_protocol/
lifecycle.rs

1use serde::{Deserialize, Serialize};
2use serde_json::Value;
3
4/// Shared lifecycle surfaces for claim-eligible and compatibility routes.
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum RuntimeLifecycleSurface {
7    A2aAuthoritative,
8    A2aCompatibility,
9    AcpAuthoritative,
10    AcpCompatibility,
11}
12
13/// Canonical runtime lifecycle contract surfaced by claim-eligible bridges.
14#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
15#[serde(rename_all = "camelCase")]
16pub struct RuntimeLifecycleContract {
17    pub surface: String,
18    pub blocking_entrypoint: String,
19    pub stream_entrypoint: String,
20    pub follow_up_entrypoint: String,
21    pub cancel_entrypoint: String,
22    pub stream_delivery: String,
23    pub partial_output_delivery: String,
24    pub claim_eligible: bool,
25    pub compatibility_only: bool,
26}
27
28#[must_use]
29pub fn runtime_lifecycle_contract(surface: RuntimeLifecycleSurface) -> RuntimeLifecycleContract {
30    match surface {
31        RuntimeLifecycleSurface::A2aAuthoritative => RuntimeLifecycleContract {
32            surface: "a2a_authoritative".to_string(),
33            blocking_entrypoint: "message/send".to_string(),
34            stream_entrypoint: "message/stream".to_string(),
35            follow_up_entrypoint: "task/get".to_string(),
36            cancel_entrypoint: "task/cancel".to_string(),
37            stream_delivery: "collated_terminal_payload".to_string(),
38            partial_output_delivery: "collated_terminal_payload".to_string(),
39            claim_eligible: true,
40            compatibility_only: false,
41        },
42        RuntimeLifecycleSurface::A2aCompatibility => RuntimeLifecycleContract {
43            surface: "a2a_compatibility".to_string(),
44            blocking_entrypoint: "message/send".to_string(),
45            stream_entrypoint: "unsupported".to_string(),
46            follow_up_entrypoint: "unsupported".to_string(),
47            cancel_entrypoint: "unsupported".to_string(),
48            stream_delivery: "collected_final_payload_only".to_string(),
49            partial_output_delivery: "collected_final_payload_only".to_string(),
50            claim_eligible: false,
51            compatibility_only: true,
52        },
53        RuntimeLifecycleSurface::AcpAuthoritative => RuntimeLifecycleContract {
54            surface: "acp_authoritative".to_string(),
55            blocking_entrypoint: "tool/invoke".to_string(),
56            stream_entrypoint: "tool/stream".to_string(),
57            follow_up_entrypoint: "tool/resume".to_string(),
58            cancel_entrypoint: "tool/cancel".to_string(),
59            stream_delivery: "resumed_terminal_payload".to_string(),
60            partial_output_delivery: "resumed_terminal_payload".to_string(),
61            claim_eligible: true,
62            compatibility_only: false,
63        },
64        RuntimeLifecycleSurface::AcpCompatibility => RuntimeLifecycleContract {
65            surface: "acp_compatibility".to_string(),
66            blocking_entrypoint: "tool/invoke".to_string(),
67            stream_entrypoint: "unsupported".to_string(),
68            follow_up_entrypoint: "unsupported".to_string(),
69            cancel_entrypoint: "unsupported".to_string(),
70            stream_delivery: "collected_final_payload_only".to_string(),
71            partial_output_delivery: "collected_final_payload_only".to_string(),
72            claim_eligible: false,
73            compatibility_only: true,
74        },
75    }
76}
77
78#[must_use]
79pub fn runtime_lifecycle_metadata(surface: RuntimeLifecycleSurface) -> Value {
80    match serde_json::to_value(runtime_lifecycle_contract(surface)) {
81        Ok(value) => value,
82        Err(_) => Value::Null,
83    }
84}