einoacp

package module
v0.0.0-...-4c282fb Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 12, 2026 License: MIT Imports: 16 Imported by: 0

README

eino-acp

Eino ChatModel provider that connects to any ACP (Agent Client Protocol) compatible coding agent.

Use Claude Code, Codex CLI, Gemini CLI, or any other ACP agent as an LLM backend for CloudWeGo Eino.

Install

go get github.com/strrl/eino-acp

Usage

package main

import (
	"context"
	"fmt"

	einoacp "github.com/strrl/eino-acp"
)

func main() {
	ctx := context.Background()

	cm, err := einoacp.NewChatModel(ctx, &einoacp.Config{
		Command: einoacp.ClaudeCommand(),
		// or: einoacp.CodexCommand()
		// or: einoacp.GeminiCommand()
	})
	if err != nil {
		panic(err)
	}

	// Generate (non-streaming)
	msg, err := cm.Generate(ctx, einoacp.UserMessages("Hello!"))
	if err != nil {
		panic(err)
	}
	fmt.Println(msg.Content)

	// Stream
	stream, err := cm.Stream(ctx, einoacp.UserMessages("Tell me a joke."))
	if err != nil {
		panic(err)
	}
	defer stream.Close()

	for {
		chunk, err := stream.Recv()
		if err != nil {
			break
		}
		fmt.Print(chunk.Content)
	}
	fmt.Println()
}

Config

Field Description
Command Command to launch the ACP agent. Use ClaudeCommand(), CodexCommand(), or GeminiCommand() helpers, which auto-detect bunx, then pnpm dlx, then npx -y. Required.
Cwd Working directory for the agent session. Defaults to current directory.
Env Additional environment variables for the agent subprocess.
AutoApprove Auto-approve all permission requests from the agent. Default false.

How it works

  1. Launches the agent as a subprocess
  2. Communicates via ACP (JSON-RPC 2.0 over stdio)
  3. Maps ACP session updates to Eino's schema.Message streaming interface

Tool Call Mapping

eino-acp translates ACP tool_call and tool_call_update session updates into Eino assistant ToolCalls.

ACP field Eino field Notes
toolCallId ToolCall.ID Preserved as-is.
kind ToolCall.Function.Name Uses ACP tool kind such as read, edit, or execute. Falls back to other when ACP omits the kind.
rawInput ToolCall.Function.Arguments JSON-marshaled into a stable string. Defaults to {} when missing.
title, status, rawOutput, locations, content, _meta ToolCall.Extra Preserved under acp_* keys so observability consumers can inspect ACP-specific metadata.

For Generate, the final assistant message includes the accumulated ToolCalls.

For Stream, each ACP tool event is emitted as an assistant chunk with empty Content and a single ToolCall, so consumers such as tape, Langfuse-style handlers, or ADK can observe tool activity as it happens.

agent_thought_chunk, plan, and other non-message ACP session updates are still ignored.

Built on coder/acp-go-sdk.

License

MIT

Documentation

Overview

Package einoacp provides an ACP-backed chat model implementation for Eino.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ClaudeCommand

func ClaudeCommand() []string

ClaudeCommand returns the command to launch Claude Code via ACP.

func CodexCommand

func CodexCommand() []string

CodexCommand returns the command to launch OpenAI Codex CLI via ACP. Uses the dedicated ACP adapter package from the ACP registry.

func GeminiCommand deprecated

func GeminiCommand() []string

GeminiCommand returns the command to launch Google Gemini CLI via ACP.

NOTE: Gemini CLI in ACP mode currently does not work with OAuth authentication when launched as a subprocess. See upstream issue: https://github.com/google-gemini/gemini-cli/issues/12042

Deprecated: Use ClaudeCommand or CodexCommand instead until this is resolved.

func UserMessages

func UserMessages(content string) []*schema.Message

UserMessages is a convenience function to create a single user message slice.

Types

type ChatModel

type ChatModel struct {
	// contains filtered or unexported fields
}

ChatModel implements eino's model.ChatModel by communicating with any ACP-compatible coding agent (Claude Code, Codex CLI, etc.) over the Agent Client Protocol.

func NewChatModel

func NewChatModel(_ context.Context, config *Config) (*ChatModel, error)

NewChatModel creates a new ACP chat model.

func (*ChatModel) BindTools

func (cm *ChatModel) BindTools(_ []*schema.ToolInfo) error

BindTools is a no-op; ACP agents manage their own tools.

func (*ChatModel) Generate

func (cm *ChatModel) Generate(_ context.Context, _ []*schema.Message, _ ...model.Option) (*schema.Message, error)

Generate is not supported for ACP-based chat models.

ACP is a streaming-only protocol: the agent emits ordered session updates (tool_call → tool_call_update → agent_message_chunk) that must be consumed in real time. Collapsing them into a single *schema.Message via Generate destroys event ordering and streaming granularity.

Use Stream instead.

func (*ChatModel) GetType

func (cm *ChatModel) GetType() string

GetType returns the component type name used by Eino callbacks.

func (*ChatModel) IsCallbacksEnabled

func (cm *ChatModel) IsCallbacksEnabled() bool

IsCallbacksEnabled reports whether callback hooks are enabled for this model.

func (*ChatModel) Stream

func (cm *ChatModel) Stream(ctx context.Context, input []*schema.Message, _ ...model.Option) (outStream *schema.StreamReader[*schema.Message], err error)

Stream runs the ACP agent and yields assistant output chunks as they arrive.

func (*ChatModel) WithTools

func (cm *ChatModel) WithTools(_ []*schema.ToolInfo) (model.ToolCallingChatModel, error)

WithTools is a no-op; ACP agents manage their own tools.

type Config

type Config struct {
	// Command is the full command to launch the ACP agent.
	// The first element is the binary, the rest are arguments.
	// Use the provided helpers: ClaudeCommand(), CodexCommand().
	// Required, must have at least one element.
	Command []string

	// Cwd is the working directory for the agent session.
	// Defaults to the current working directory.
	Cwd string

	// Env sets additional environment variables for the agent subprocess.
	// These are merged with the current process environment.
	Env []string

	// AutoApprove automatically approves all permission requests from the agent.
	// When false, permission requests are denied.
	AutoApprove bool

	// OnSessionUpdate is called for every ACP SessionUpdate received during
	// execution. This fires in real-time regardless of whether Generate() or
	// Stream() is used, giving consumers access to tool calls, text chunks,
	// and other ACP events as they happen.
	OnSessionUpdate func(acp.SessionUpdate)

	// McpServers is the list of MCP servers to attach to each ACP session.
	// Claude Code will discover and use tools from these servers.
	McpServers []acp.McpServer
}

Config for the ACP-based chat model.

Directories

Path Synopsis
Example demonstrates how to use the ACP chat model with Eino.
Example demonstrates how to use the ACP chat model with Eino.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL