#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ConnectorKind {
Fake,
LlmHttp,
GrokBuild,
Cursor,
Antigravity,
Codex,
Zai,
Claude,
Other(String),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum RawBoundary {
InProcess,
HttpBody,
WebSocketMessage,
ProcessPipe,
Socket,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ControlCapabilities {
pub cancel: bool,
pub terminate: bool,
pub input_finish: bool,
}
impl Default for ControlCapabilities {
fn default() -> Self {
Self {
cancel: true,
terminate: true,
input_finish: true,
}
}
}
#[derive(Clone, Debug)]
pub struct ConnectorDescriptor {
pub connector_kind: ConnectorKind,
pub implementation_id: String,
pub implementation_version: String,
pub transport_kind: String,
pub supported_dialects: Vec<String>,
pub raw_boundary: RawBoundary,
pub control_capabilities: ControlCapabilities,
}
impl ConnectorDescriptor {
pub fn fake() -> Self {
Self {
connector_kind: ConnectorKind::Fake,
implementation_id: "monoloop.fake".into(),
implementation_version: env!("CARGO_PKG_VERSION").into(),
transport_kind: "in_process".into(),
supported_dialects: vec!["test/raw".into()],
raw_boundary: RawBoundary::InProcess,
control_capabilities: ControlCapabilities::default(),
}
}
pub fn grok_build() -> Self {
Self {
connector_kind: ConnectorKind::GrokBuild,
implementation_id: "monoloop.grok_build".into(),
implementation_version: env!("CARGO_PKG_VERSION").into(),
transport_kind: "websocket".into(),
supported_dialects: vec!["acp/json_rpc".into()],
raw_boundary: RawBoundary::WebSocketMessage,
control_capabilities: ControlCapabilities::default(),
}
}
pub fn cursor_acp() -> Self {
Self {
connector_kind: ConnectorKind::Cursor,
implementation_id: "monoloop.cursor_acp".into(),
implementation_version: env!("CARGO_PKG_VERSION").into(),
transport_kind: "process_stdio".into(),
supported_dialects: vec!["acp/json_rpc".into(), "cursor_acp/ndjson".into()],
raw_boundary: RawBoundary::ProcessPipe,
control_capabilities: ControlCapabilities::default(),
}
}
pub fn agy_acp() -> Self {
Self {
connector_kind: ConnectorKind::Antigravity,
implementation_id: "monoloop.agy_acp".into(),
implementation_version: env!("CARGO_PKG_VERSION").into(),
transport_kind: "process_stdio".into(),
supported_dialects: vec!["acp/json_rpc".into(), "agy_acp/ndjson".into()],
raw_boundary: RawBoundary::ProcessPipe,
control_capabilities: ControlCapabilities::default(),
}
}
pub fn codex_acp() -> Self {
Self {
connector_kind: ConnectorKind::Codex,
implementation_id: "monoloop.codex_acp".into(),
implementation_version: env!("CARGO_PKG_VERSION").into(),
transport_kind: "process_stdio".into(),
supported_dialects: vec!["acp/json_rpc".into(), "codex_acp/ndjson".into()],
raw_boundary: RawBoundary::ProcessPipe,
control_capabilities: ControlCapabilities::default(),
}
}
pub fn zai_cli() -> Self {
Self {
connector_kind: ConnectorKind::Zai,
implementation_id: "monoloop.zai_cli".into(),
implementation_version: env!("CARGO_PKG_VERSION").into(),
transport_kind: "process_stdio".into(),
supported_dialects: vec!["zai_cli/ndjson".into(), "openai_chat/ndjson".into()],
raw_boundary: RawBoundary::ProcessPipe,
control_capabilities: ControlCapabilities::default(),
}
}
pub fn claude_code() -> Self {
Self {
connector_kind: ConnectorKind::Claude,
implementation_id: "monoloop.claude_code".into(),
implementation_version: env!("CARGO_PKG_VERSION").into(),
transport_kind: "process_stdio".into(),
supported_dialects: vec![
"claude_code/stream_json".into(),
"claude_code/ndjson".into(),
],
raw_boundary: RawBoundary::ProcessPipe,
control_capabilities: ControlCapabilities::default(),
}
}
}