feat(helexa-acp): wire ACP agent loop for text-only conversations
Some checks failed
build-prerelease / Package helexa-neuron-ada RPM (push) Blocked by required conditions
build-prerelease / Package helexa-neuron-ampere RPM (push) Blocked by required conditions
build-prerelease / Package helexa-neuron-blackwell RPM (push) Blocked by required conditions
build-prerelease / Resolve version stamps (push) Successful in 41s
CI / Format (push) Successful in 38s
CI / Clippy (push) Successful in 2m35s
build-prerelease / Build cortex binary (push) Successful in 5m26s
CI / Test (push) Successful in 5m43s
build-prerelease / Build neuron-blackwell (push) Successful in 5m47s
CI / Build cortex SRPM (push) Has been skipped
CI / Build neuron SRPM (push) Has been skipped
CI / Publish cortex to COPR (push) Has been skipped
CI / Publish neuron to COPR (push) Has been skipped
CI / Bump version in source (push) Has been skipped
build-prerelease / Package cortex RPM (push) Successful in 1m23s
build-prerelease / Build neuron-ampere (push) Successful in 8m13s
build-prerelease / Build neuron-ada (push) Successful in 5m28s
build-prerelease / Publish to rpm.lair.cafe (unstable) (push) Has been cancelled
Some checks failed
build-prerelease / Package helexa-neuron-ada RPM (push) Blocked by required conditions
build-prerelease / Package helexa-neuron-ampere RPM (push) Blocked by required conditions
build-prerelease / Package helexa-neuron-blackwell RPM (push) Blocked by required conditions
build-prerelease / Resolve version stamps (push) Successful in 41s
CI / Format (push) Successful in 38s
CI / Clippy (push) Successful in 2m35s
build-prerelease / Build cortex binary (push) Successful in 5m26s
CI / Test (push) Successful in 5m43s
build-prerelease / Build neuron-blackwell (push) Successful in 5m47s
CI / Build cortex SRPM (push) Has been skipped
CI / Build neuron SRPM (push) Has been skipped
CI / Publish cortex to COPR (push) Has been skipped
CI / Publish neuron to COPR (push) Has been skipped
CI / Bump version in source (push) Has been skipped
build-prerelease / Package cortex RPM (push) Successful in 1m23s
build-prerelease / Build neuron-ampere (push) Successful in 8m13s
build-prerelease / Build neuron-ada (push) Successful in 5m28s
build-prerelease / Publish to rpm.lair.cafe (unstable) (push) Has been cancelled
Stage 2 lands the agent loop on top of the Stage 1 scaffold: session state with per-session cancellation, a system-prompt builder honouring HELEXA_ACP_SYSTEM_PROMPT_PATH / system_prompt_path TOML, and handlers for initialize / session/new / session/prompt / session/cancel that stream provider output back as session/update notifications. Verified end-to-end against cortex from Zed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,23 +2,26 @@
|
||||
//! setups (helexa, LM Studio, Ollama, OpenRouter, OpenAI, Anthropic,
|
||||
//! …) with a clean per-endpoint wire-format selector.
|
||||
//!
|
||||
//! Speaks ACP over stdio to an editor client (Zed today). The
|
||||
//! conversation is forwarded to one of the configured endpoints via
|
||||
//! a wire-format-specific [`provider::Provider`] implementation.
|
||||
//! The agent loop itself is provider-agnostic — adding e.g. an
|
||||
//! Anthropic /v1/messages provider doesn't touch `agent.rs`.
|
||||
//! Speaks ACP over stdio to an editor client (Zed today). Every
|
||||
//! configured endpoint produces a wire-format-specific
|
||||
//! [`provider::Provider`] implementation; the agent loop in
|
||||
//! [`agent::Agent`] is provider-agnostic, so adding e.g. an Anthropic
|
||||
//! /v1/messages provider doesn't touch `agent.rs`.
|
||||
//!
|
||||
//! Config: `$XDG_CONFIG_HOME/helexa-acp/config.toml` for the multi-
|
||||
//! endpoint case; env vars (`HELEXA_ACP_BASE_URL`, etc.) for the
|
||||
//! single-endpoint case when no config file exists.
|
||||
|
||||
use agent_client_protocol::schema::{AgentCapabilities, InitializeRequest, InitializeResponse};
|
||||
use agent_client_protocol::{Agent, Client, ConnectionTo, Dispatch, Result, Stdio};
|
||||
use agent_client_protocol::{Result, Stdio};
|
||||
use std::sync::Arc;
|
||||
|
||||
mod agent;
|
||||
mod config;
|
||||
mod prompt;
|
||||
mod provider;
|
||||
mod session;
|
||||
|
||||
use agent::Agent;
|
||||
use config::{Config, EndpointConfig, WireApi};
|
||||
use provider::{Provider, openai_chat::OpenAIChatProvider};
|
||||
|
||||
@@ -86,36 +89,8 @@ async fn main() -> Result<()> {
|
||||
}
|
||||
}
|
||||
}
|
||||
if providers.is_empty() {
|
||||
return Err(agent_client_protocol::util::internal_error(
|
||||
"no usable endpoints — check config",
|
||||
));
|
||||
}
|
||||
|
||||
Agent
|
||||
.builder()
|
||||
.name("helexa-acp")
|
||||
.on_receive_request(
|
||||
async move |initialize: InitializeRequest, responder, _connection| {
|
||||
// Phase 1 wiring — capabilities only. Real session
|
||||
// handling lands in the next iteration (agent.rs).
|
||||
responder.respond(
|
||||
InitializeResponse::new(initialize.protocol_version)
|
||||
.agent_capabilities(AgentCapabilities::new()),
|
||||
)
|
||||
},
|
||||
agent_client_protocol::on_receive_request!(),
|
||||
)
|
||||
.on_receive_dispatch(
|
||||
async move |message: Dispatch, cx: ConnectionTo<Client>| {
|
||||
tracing::warn!(method = ?message.method(), "unhandled ACP message");
|
||||
message.respond_with_error(
|
||||
agent_client_protocol::util::internal_error("not implemented yet"),
|
||||
cx,
|
||||
)
|
||||
},
|
||||
agent_client_protocol::on_receive_dispatch!(),
|
||||
)
|
||||
.connect_to(Stdio::new())
|
||||
.await
|
||||
let agent = Agent::new(&cfg, providers)
|
||||
.map_err(|e| agent_client_protocol::util::internal_error(format!("agent: {e:#}")))?;
|
||||
agent.serve(Stdio::new()).await
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user