netget/server/adc/
actions.rs1use crate::llm::actions::{
2 protocol_trait::{ActionResult, Protocol, Server},
3 ActionDefinition,
4};
5use crate::protocol::{EventType, SpawnContext};
6use crate::server::p2p_support::{action, parameter};
7use crate::state::AppState;
8use anyhow::{ensure, Result};
9use serde_json::{json, Value};
10use std::{
11 future::Future,
12 net::SocketAddr,
13 pin::Pin,
14 sync::{Arc, LazyLock},
15};
16
17#[derive(Default)]
18pub struct AdcProtocol;
19impl AdcProtocol {
20 pub fn new() -> Self {
21 Self
22 }
23}
24pub fn reply() -> ActionDefinition {
25 action(
26 "adc_reply",
27 "Handler-approved identities, public/private chat, search and peer-connect routing",
28 vec![parameter(
29 "accepted",
30 "boolean",
31 "Approve identification or forwarding",
32 true,
33 )],
34 json!({"type":"adc_reply","accepted":false}),
35 )
36}
37impl Protocol for AdcProtocol {
38 fn protocol_name(&self) -> &'static str {
39 "ADC"
40 }
41 fn stack_name(&self) -> &'static str {
42 "ETH>IP>TCP>ADC"
43 }
44 fn keywords(&self) -> Vec<&'static str> {
45 vec!["adc", "adc"]
46 }
47 fn description(&self) -> &'static str {
48 "Selected ADC hub and peer operations listening role"
49 }
50 fn example_prompt(&self) -> &'static str {
51 "Listen on ADC port 1511; supply protocol decisions with handlers"
52 }
53 fn group_name(&self) -> &'static str {
54 "Peer-to-peer"
55 }
56 fn get_startup_parameters(&self) -> Vec<crate::llm::actions::ParameterDefinition> {
57 crate::server::p2p_support::tls_parameters(true)
58 }
59 fn get_startup_examples(&self) -> crate::llm::actions::StartupExamples {
60 let base = json!({"type":"open_server","base_stack":"adc","port":1511,"instruction":"Serve selected ADC operations"});
61 let mut fixed = base.clone();
62 fixed["event_handlers"] = json!([{"event_pattern":"adc_request","handler":{"type":"static","actions":[reply().example]}}]);
63 let mut script = base.clone();
64 script["event_handlers"] = json!([{"event_pattern":"adc_request","handler":{"type":"script","language":"python","code":"import json,sys\ne=json.load(sys.stdin)['event']\nprint(json.dumps({'actions':[{'type':'adc_reply','error':'denied'}]}))"}}]);
65 crate::llm::actions::StartupExamples::new(base, script, fixed)
66 }
67 fn get_async_actions(&self, _: &AppState) -> Vec<ActionDefinition> {
68 vec![action(
69 "disconnect",
70 "Close this peer",
71 vec![],
72 json!({"type":"disconnect"}),
73 )]
74 }
75 fn get_sync_actions(&self) -> Vec<ActionDefinition> {
76 vec![reply()]
77 }
78 fn get_event_types(&self) -> Vec<EventType> {
79 EVENTS.clone()
80 }
81 fn metadata(&self) -> crate::protocol::ProtocolMetadataV2 {
82 crate::protocol::ProtocolMetadataV2::builder().state(crate::protocol::metadata::DevelopmentState::Experimental).implementation("Native bounded ADC selected codec; TCP and optional implicit TLS").llm_control("Handler-approved identities, public/private chat, search and peer-connect routing").e2e_testing("Independent peer exchanges, malformed input, owner shutdown and standalone feature builds").notes("ADC 1.0 BASE/TIGR, anonymous identities with CID/PID validation and per-connection IDs. ADCS uses verified implicit TLS. Selected BINF/BMSG/DMSG/BSCH/DRES/DCTM/DRCM routing. No GPA/PAS password login, UDP search, NAT traversal or persistent hub account database. 256 connections, 30 s first frame, 600 s idle, 10 s handshake/exchange. No persistent protocol data; handlers supply content and decisions.").max_inbound_bytes(super::codec::MAX_COMMAND).well_known_port(1511).build()
83 }
84}
85impl Server for AdcProtocol {
86 fn spawn(&self, ctx: SpawnContext) -> Pin<Box<dyn Future<Output = Result<SocketAddr>> + Send>> {
87 {
88 let hub = Arc::new(super::codec::Hub::default());
89 Box::pin(crate::server::p2p_support::spawn(
90 ctx,
91 Arc::new(Self),
92 move || super::codec::Device::new(hub.clone()),
93 &EVENTS,
94 ))
95 }
96 }
97 fn execute_action(&self, v: Value) -> Result<ActionResult> {
98 if v["type"] == "disconnect" {
99 return Ok(ActionResult::CloseConnection);
100 }
101 ensure!(v["type"] == "adc_reply", "unknown action");
102 Ok(ActionResult::Custom {
103 name: "adc_reply".into(),
104 data: v,
105 })
106 }
107}
108pub static EVENTS: LazyLock<Vec<EventType>> = LazyLock::new(|| {
109 vec![EventType::new(
110 "adc_request",
111 "Handler-approved identities, public/private chat, search and peer-connect routing",
112 reply().example,
113 )
114 .with_actions(vec![reply()])
115 .with_parameters(vec![
116 parameter("operation", "string", "Selected protocol operation", true),
117 parameter(
118 "identifier",
119 "string",
120 "Requested object, message or file identifier",
121 false,
122 ),
123 ])]
124});