Files
enkly-ai/api/proto/agent/v1/agent.proto
enkly 79ce8dc4c0
Some checks failed
Go CI Pipeline / build_and_test (push) Failing after 22m0s
Init Project
2026-10-30 18:06:55 +01:00

160 lines
6.2 KiB
Protocol Buffer

// Package agent is the Agent Orchestration bounded context: the agentic
// run loop (prompt -> vLLM -> tool calls -> final reply), the chat-run
// quota/concurrency guard, and the in-flight/just-finished run registry
// that used to live in internal/handlers/chat.go's StreamManager.
//
// This is a saga coordinator, not a data owner: it holds no SQL table of
// its own. It calls billing (usage quota), conversation (persisting
// turns) and knowledge (the search_codebase tool) over gRPC, and
// workspace (every filesystem/bash tool) over gRPC, exactly replacing
// internal/llm/agent.go + internal/llm/tools.go's direct, in-process
// calls into internal/db and the local filesystem.
//
// Rendering (Markdown, syntax highlighting, deliverable cards) stays out
// of this service on purpose — see internal/render's doc comment in the
// gateway service — so this API deals in plain text and structured tool
// results, never HTML.
syntax = "proto3";
package enkly.agent.v1;
option go_package = "enkly/gen/agent/v1;agentv1";
service AgentService {
// StartTurn replaces the synchronous prefix of Handlers.Chat: the
// per-user throttle (ChatLimiter), the billing quota check, loading
// the conversation, persisting the user's prompt, auto-titling, and
// registering a new run (StreamManager.create) before handing off to
// a background goroutine. Returns immediately with a stream_id; the
// reply itself arrives via StreamTurn.
rpc StartTurn(StartTurnRequest) returns (StartTurnResponse);
// StreamTurn replaces Handlers.StreamChat: a server-streaming view of
// one run's progress. resume_from_tool_index mirrors the monolith's
// SSE Last-Event-ID handling, so a reconnecting client doesn't see
// tool cards it already has.
rpc StreamTurn(StreamTurnRequest) returns (stream TurnEvent);
// StopTurn replaces Handlers.StopStream.
rpc StopTurn(StopTurnRequest) returns (StopTurnResponse);
}
enum StartTurnOutcome {
START_TURN_OUTCOME_UNSPECIFIED = 0;
START_TURN_OUTCOME_OK = 1;
START_TURN_OUTCOME_CONVERSATION_NOT_FOUND = 2;
START_TURN_OUTCOME_CONVERSATION_BUSY = 3;
START_TURN_OUTCOME_TOO_MANY_STREAMS = 4;
START_TURN_OUTCOME_RATE_LIMITED = 5;
START_TURN_OUTCOME_QUOTA_EXCEEDED = 6;
START_TURN_OUTCOME_INTERNAL_ERROR = 7;
}
// SystemEntry is a mid-conversation instruction/permission/budget
// update — see agentrun.SystemEntry (services/agent/internal/
// infrastructure/agentrun/effort.go) for what each kind means and how
// it's folded into the system prompt.
message SystemEntry {
enum Kind {
KIND_UNSPECIFIED = 0;
KIND_INSTRUCTION = 1;
KIND_PERMISSION = 2;
KIND_BUDGET = 3;
}
Kind kind = 1;
string content = 2;
}
message StartTurnRequest {
int64 user_id = 1;
int64 conversation_id = 2;
string prompt = 3;
// --- Fields below this line are the TARGET structured API surface
// for effort control, fast mode and live system-entry updates — see
// pkg/turnopts' package doc comment for why they aren't wired up yet
// (this environment has no protoc/go toolchain to regenerate
// gen/agent/v1 from this file) and what the working fallback is
// today (leading /effort, /fast, /system directive lines parsed out
// of `prompt` itself, by pkg/turnopts.Parse — see
// application.Service.StartTurn). Once `make proto` is run against
// this file, a follow-up change points StartTurn at these fields
// directly, with turnopts kept on as the fallback path for any
// client that still sends plain-text directives instead. Proto3
// fields are purely additive and backward compatible to add, so
// declaring them now costs nothing even before that regeneration —
// every field below defaults to its zero value for any client built
// against today's compiled stubs.
// effort selects one of pkg/effort's five levels ("low", "medium",
// "high", "extra", "max") for this turn; empty means "use the
// deployment's configured default" (see agentrun.Agent.Effort).
string effort = 4;
// fast_mode requests fast mode for this turn (see
// application.Service.FastAgent) — available on every plan, unlike
// dynamic_workflows below.
bool fast_mode = 5;
// system_entries are folded into the system prompt for this turn
// onward (see agentrun.WithSystemEntries) — appended, never
// replacing anything, so earlier turns' prefix stays stable.
repeated SystemEntry system_entries = 6;
}
message StartTurnResponse {
StartTurnOutcome outcome = 1;
string message = 2; // user-facing text for any non-OK outcome
string stream_id = 3; // set when outcome == OK
}
message StreamTurnRequest {
int64 user_id = 1;
string stream_id = 2;
int32 resume_from_tool_index = 3;
}
message ToolCall {
string name = 1;
string arguments_json = 2;
string result = 3;
bool is_error = 4;
}
// ThinkingRound is one agent round's own reasoning trace, standalone
// rather than folded into the running total thinking_delta carries —
// the same per-step granularity Claude's interleaved thinking exposes
// (one distinct thinking block per tool-use step) rather than one
// cumulative blob for the whole turn. round is 0-indexed and matches
// the round the agent service's internal run loop was on when this
// trace was produced; a client can use it to render reasoning as
// discrete, collapsible steps next to the tool call each one preceded,
// instead of a single growing "thinking" pane.
message ThinkingRound {
int32 round = 1;
string thinking = 2;
}
message TurnEvent {
oneof event {
string thinking_delta = 1; // cumulative reasoning text so far, plain
string token_delta = 2; // cumulative reply text so far, plain
ToolCall tool_call = 3; // one completed tool call
TurnDone done = 4;
ThinkingRound thinking_round = 5; // one round's own reasoning trace, standalone
}
}
message TurnDone {
string final_text = 1; // plain Markdown source, not yet rendered
// every tool call made during the turn, successful or not — the
// gateway uses this to build deliverable (download) cards exactly
// like internal/handlers/deliverables.go.attachDeliverables.
repeated ToolCall tool_calls = 2;
}
message StopTurnRequest {
int64 user_id = 1;
string stream_id = 2;
}
message StopTurnResponse {}