Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 11 additions & 66 deletions kontext/agent/v1/agent.proto
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,30 @@ syntax = "proto3";

package kontext.agent.v1;

// AgentService is the bidirectional streaming service between the CLI sidecar
// and the Kontext backend. The sidecar maintains a persistent connection and
// streams hook events for policy evaluation and telemetry.
// AgentService handles session lifecycle and hook event streaming
// between the CLI sidecar and the Kontext backend.
//
// Authentication: the user's OIDC bearer token from `kontext login`.
// The backend verifies the JWT and derives org + user identity.
//
// Credential exchange uses the existing OAuth token exchange endpoint
// (POST /oauth2/token, RFC 8693) — not this service.
service AgentService {
// ProcessHookEvent streams tool call events from the CLI to the backend
// and receives policy decisions in return. Bidirectional streaming keeps
// the connection open for the session lifetime — no per-hook HTTP overhead.
// the connection open for the session lifetime.
rpc ProcessHookEvent(stream ProcessHookEventRequest) returns (stream ProcessHookEventResponse);

// CreateSession establishes a governed agent session. Called once at the
// start of `kontext start`. Returns session context used for all subsequent
// hook evaluations.
// start of `kontext start`.
rpc CreateSession(CreateSessionRequest) returns (CreateSessionResponse);

// Heartbeat keeps the session alive. The sidecar sends heartbeats on an
// interval; the backend marks sessions as disconnected if heartbeats stop.
rpc Heartbeat(HeartbeatRequest) returns (HeartbeatResponse);

// EndSession terminates the session and revokes any ephemeral credentials.
// EndSession terminates the session.
rpc EndSession(EndSessionRequest) returns (EndSessionResponse);

// ExchangeCredential resolves a provider credential for a given user and
// provider handle. Used by the env template hydration and per-tool-call
// credential injection.
rpc ExchangeCredential(ExchangeCredentialRequest) returns (ExchangeCredentialResponse);

// SyncPolicy streams the current policy state for the session's org/agent.
// The sidecar caches this locally for fast hook evaluation. The server
// pushes updates when policy changes.
rpc SyncPolicy(SyncPolicyRequest) returns (stream SyncPolicyResponse);
}

// --- Hook Events ---
Expand All @@ -51,8 +45,6 @@ message ProcessHookEventResponse {
Decision decision = 1;
string reason = 2;
string event_id = 3;
// Credential to inject for this tool call (if applicable)
CredentialInjection credential = 4;
}
Comment on lines 45 to 48
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Removed field number 4 from ProcessHookEventResponse not marked as reserved, risking future wire-format conflicts

The credential field (number 4) was removed from ProcessHookEventResponse without adding a reserved 4; declaration. Per the protobuf documentation, if a future contributor reuses field number 4 for a different type or semantic, older clients/servers that still have the old schema will silently misinterpret the wire data, causing data corruption. This is especially important in this repo since it's a shared contract between the CLI and API (README.md:2-3), and buf breaking is configured to enforce backward compatibility (buf.yaml).

(Refers to lines 44-48)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


enum Decision {
Expand All @@ -62,11 +54,6 @@ enum Decision {
DECISION_ASK = 3; // Prompt user for approval
}

message CredentialInjection {
string provider = 1;
map<string, string> env_vars = 2; // e.g., {"GITHUB_TOKEN": "gho_..."}
}

// --- Sessions ---

message CreateSessionRequest {
Expand Down Expand Up @@ -95,45 +82,3 @@ message EndSessionRequest {
}

message EndSessionResponse {}

// --- Credentials ---

message ExchangeCredentialRequest {
string provider = 1; // e.g., "github", "stripe", "postgres"
string user_id = 2;
string resource = 3; // optional: specific resource URI
}

message ExchangeCredentialResponse {
string provider = 1;
CredentialKind kind = 2;
string access_token = 3; // for OAuth providers
string value = 4; // for API key providers
string token_type = 5;
string scope = 6;
int64 expires_in = 7; // seconds
}

enum CredentialKind {
CREDENTIAL_KIND_UNSPECIFIED = 0;
CREDENTIAL_KIND_OAUTH = 1;
CREDENTIAL_KIND_KEY = 2;
}

// --- Policy Sync ---

message SyncPolicyRequest {
string session_id = 1;
}

message SyncPolicyResponse {
// OpenFGA tuples for local evaluation
repeated PolicyTuple tuples = 1;
bool full_sync = 2; // true = replace all, false = incremental
}

message PolicyTuple {
string user = 1;
string relation = 2;
string object = 3;
}
Loading