160 lines
6.2 KiB
Protocol Buffer
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 {}
|