This branch removes the external ACP (Agent Communication Protocol) backend bridge from the pikachat daemon, eliminating the ability to spawn and manage a secondary ACP-speaking agent process over stdio JSON-RPC. The ACP session manager, its queued prompt pipeline, all related CLI flags (--acp-exec, --acp-cwd), the agent harness module, and the pinned pi-agent Nix package are deleted. In their place, the forge lane manifest used by pikaci is embedded at compile time via include_str! instead of being read from disk at runtime, and the Nix build fileset is updated to include the ci/ directory so the manifest is available during the build. The PI_MODEL environment variable is also dropped from the managed VM guest passthrough list.
Tutorial Steps
Remove the ACP backend module and all session management logic
Intent: Delete the entire ACP backend bridge — the stdio JSON-RPC client, session manager, queued prompt pipeline, and all associated types and tests — since the daemon no longer hosts a secondary ACP agent alongside the native protocol surface.
@@ -1,800 +0,0 @@ -//! Generic ACP backend/session bridge for the daemon host.
@@ -2,15 +2,14 @@ -pub mod acp; +//! - the daemon only serves the native protocol surface; no secondary ACP backend bridge +//! is hosted here anymore.
The acp.rs module (~800 lines) is deleted in its entirety. This module contained:
AcpBackendConfig — configuration struct holding the shell command and working directory for an external ACP agent.
AcpJsonRpcClient — an async JSON-RPC 2.0 client that communicated with the ACP backend over stdin/stdout, handling requests, responses, and session/update streaming notifications.
AcpSessionManager — conversation-to-session mapping layer that created ACP sessions on demand via session/new and routed prompts through session/prompt.
AcpBackendManager — a higher-level queue-based manager that serialized prompts per conversation and delivered completions through an unbounded channel.
default_acp_cwd() helper.
Comprehensive integration tests using a fake Python ACP backend script.
In lib.rs, the pub mod acp; declaration is removed and the crate-level doc comment is updated to state that no secondary ACP backend bridge is hosted anymore.
Remove ACP integration from the daemon event loop
Intent: Strip all ACP-related plumbing from the daemon — the completion receiver select arm, the prompt-enqueue logic on incoming messages, and the helper functions that decided whether to prompt the ACP backend.
@@ -5791,35 +5695,13 @@ - if let Some(acp) = acp_backend.as_ref()
Several intertwined pieces are removed from daemon.rs:
Import of ACP types — The use crate::acp::{AcpBackendConfig, AcpBackendManager, AcpTurnCompletion} import is deleted.
Helper functions — should_prompt_acp_reply() (which gated ACP prompts on classification, sender identity, and non-empty content) and build_acp_prompt() (which formatted the Nostr group context into an ACP prompt string) are removed.
daemon_main signature — The acp_backend: Option<AcpBackendConfig> parameter is removed. Inside the function, the block that conditionally spawned AcpBackendManager::spawn(config) and stored the completion receiver is deleted.
Select arm for ACP completions — The acp_completion = async { ... } arm in the main tokio::select! loop, which processed AcpTurnCompletion results (publishing reply messages on success, logging warnings on failure), is removed entirely.
Prompt enqueue on incoming messages — After processing an incoming chat message, the code that checked should_prompt_acp_reply, called build_acp_prompt, and enqueued via acp.enqueue_prompt() is deleted. Variables like acp_nostr_group_id, acp_sender_hex, and acp_content that were only used for this purpose are also removed.
Variable rename — The classification binding from the message interpretation match is prefixed with _ since it is no longer consumed by the ACP prompt logic.
Tests — acp_prompt_mapping_keeps_group_and_sender_context and acp_prompt_trigger_skips_self_and_empty_messages are deleted.
Remove ACP CLI flags from the daemon command
Intent: Remove the --acp-exec and --acp-cwd command-line arguments and their forwarding through cmd_daemon, so the daemon binary no longer accepts ACP configuration.
Affected files: cli/src/main.rs
Evidence
@@ -372,15 +372,6 @@ - /// Spawn an external ACP-speaking backend over stdio JSON-RPC - #[arg(long)] - acp_exec: Option<String>, - /// Working directory passed to ACP `session/new` - #[arg(long)] - acp_cwd: Option<PathBuf>,
Command::Daemon variant — The acp_exec: Option<String> and acp_cwd: Option<PathBuf> fields (with their doc comments) are removed from the Daemon variant of the CLI enum.
Match arm — The destructuring of acp_exec and acp_cwd in the main match block, and their forwarding to cmd_daemon(), are removed.
cmd_daemon function — The acp_exec and acp_cwd parameters are removed from the signature. The body no longer constructs an AcpBackendConfig or passes acp_backend to daemon_main().
Test — daemon_command_parses_acp_backend_flags is deleted since the flags no longer exist.
Delete the agent harness module
Intent: Remove the agent harness abstraction that wrapped the Marmot session builder for ACP protocol use, as it is no longer needed without the ACP backend.
AcpMarmotSession — a concrete implementation wrapping MarmotSessionBuilder for the ACP protocol.
new_harness_session() factory function.
Three unit tests validating envelope round-tripping and idempotency key uniqueness.
The mod.rs for the agent module is updated to remove pub mod harness;.
Embed the forge lane manifest at compile time
Intent: Switch pikaci from reading the forge-lanes.toml manifest from disk at runtime to embedding it in the binary via include_str!, eliminating the runtime file dependency and the CARGO_MANIFEST_DIR-relative path resolution.
A compile-time constant FORGE_MANIFEST_TOML is introduced using include_str!("../../../ci/forge-lanes.toml"), which embeds the manifest file contents directly into the binary.
load_branch_lane_paths() now calls toml::from_str(FORGE_MANIFEST_TOML) directly instead of std::fs::read_to_string(manifest_path()). The error context message is updated from "parse forge lane manifest" to "parse embedded forge lane manifest".
The manifest_path() helper function and the use std::path::Path import are removed since they are no longer needed.
This change makes the pikaci binary self-contained with respect to forge lane configuration — it no longer needs the source tree present at runtime.
Include ci/ directory in the Nix build fileset
Intent: Add the ci/ directory to the Nix fileset so that the forge-lanes.toml file is available in the build sandbox for include_str! to reference during compilation.
Affected files: flake.nix
Evidence
@@ -182,6 +182,7 @@ + ./ci
A single line is added to the fileset unions list in the Nix mkPikaciSrc (or equivalent Cargo source derivation):
Without this addition, the Nix build sandbox would not contain ci/forge-lanes.toml, causing the include_str! macro in forge_manifest.rs to fail at compile time.
Remove the pinned pi-agent Nix package
Intent: Delete the pi-agent-runtime Nix package definition and its npm lockfile, removing the pinned @mariozechner/pi-coding-agent dependency from the project.
The Nix flake previously defined piAgentPkg, a buildNpmPackage derivation that pinned @mariozechner/pi-coding-agent at version 0.54.2 and exposed it as a pi binary. This is removed:
flake.nix — The entire piAgentPkg definition (~25 lines) is deleted, along with its entry in packages."x86_64-linux" (pi-agent-runtime = piAgentPkg;).
nix/pi-agent/package-lock.json — The 3,826-line npm lockfile is deleted.
nix/pi-agent/package.json — The package manifest is deleted.
This removes the pi coding agent runtime from the project's Nix outputs entirely.
Drop PI_MODEL from managed VM environment passthrough
Intent: Remove the PI_MODEL environment variable from the list forwarded into managed OpenClaw VM guests, since the pi agent runtime that consumed it has been removed.
@@ -182,7 +182,7 @@ - for key in ["ANTHROPIC_API_KEY", "OPENAI_API_KEY", "PI_MODEL"] { + for key in ["ANTHROPIC_API_KEY", "OPENAI_API_KEY"] {
In build_managed_guest_autostart, the environment variable passthrough loop previously forwarded ANTHROPIC_API_KEY, OPENAI_API_KEY, and PI_MODEL into the guest VM. PI_MODEL is removed from the list since the pi agent that consumed this variable is no longer part of the system. The remaining two API key variables continue to be forwarded.