Agent API
Table of Contents
upsquad/agent/v1/agent.proto
Agent
Agent represents an AI agent instance within the scope hierarchy.
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | id is the UUID of the agent. | |
| org_id | string | org_id is the tenant organisation UUID. | |
| pillar_id | string | pillar_id is the business unit UUID. | |
| team_id | string | team_id is the team UUID the agent belongs to. | |
| name | string | name is the human-readable agent name. | |
| clearance | int32 | clearance is the agent's clearance level (1-5). | |
| created_at | google.protobuf.Timestamp | created_at is when the agent was provisioned. | |
| deleted_at | google.protobuf.Timestamp | deleted_at is set when the agent is soft-deleted; null for active agents. | |
| is_headless | bool | is_headless indicates the agent was provisioned via RegisterAgent (API). | |
| status | string | status is the agent runtime status: "active" (default) or "paused". GAP-37 (#1085) — set by PauseAgent / ResumeAgent. Empty string is treated as "active" for forward-compat with rows persisted before migration 083 was applied. |
AgentConfiguration
AgentConfiguration holds per-agent configuration data.
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | id is the configuration record UUID. | |
| agent_id | string | agent_id is the UUID of the agent this configuration belongs to. | |
| persona | string | persona is the agent's system prompt / persona text. | |
| model_id | string | model_id is the LLM model identifier (e.g. "claude-sonnet-4-20250514"). | |
| tools | string | tools is the per-agent MCP allowlist: a JSON array of mcp_servers UUIDs that NARROWS the agent's team-resolved MCP set (ADR-0022 W3/B8, #1744). Empty/absent = inherit ALL team MCP servers. REPURPOSED from the legacy tool-definitions array (the static-list read is bypassed by the v2.4 resolver). | |
| config | string | config is a JSON-encoded map of arbitrary configuration. | |
| updated_at | google.protobuf.Timestamp | updated_at is the last modification timestamp. |
AgentTemplate
AgentTemplate is one entry in the prototype-template catalog backing the redesigned 4-step Deploy wizard. Fields mirror the wizard's step-1 card semantics.
| Field | Type | Label | Description |
|---|---|---|---|
| id | string | id is the stable template identifier (e.g. "support-triage"). | |
| name | string | name is the short display name shown in the wizard card title. | |
| description | string | description is the one-paragraph summary shown under the name. | |
| icon | string | icon is a stable icon token the client maps to its icon registry (e.g. "lifebuoy", "receipt", "search", "wrench"). | |
| default_actions | string | repeated | default_actions is the seed list of actions the wizard pre-populates for this template. Free-form strings — the agent persona text synthesises them into a system prompt at deploy time. |
| best_for | string | best_for is the "use this when…" tagline shown on the card. |
BudgetStatus
BudgetStatus mirrors GetBudgetStatusResponse but is embedded inline on each ListAgentRow to avoid the N+1 the redesigned Agents directory would otherwise incur (one GetBudgetStatus per row). GAP-21 (#1084).
| Field | Type | Label | Description |
|---|---|---|---|
| daily_token_cap | int64 | daily_token_cap is the configured daily token limit (0 = unlimited). | |
| monthly_token_cap | int64 | monthly_token_cap is the configured monthly token limit (0 = unlimited). | |
| daily_cost_cap | double | daily_cost_cap is the configured daily cost limit in USD (0 = unlimited). | |
| monthly_cost_cap | double | monthly_cost_cap is the configured monthly cost limit in USD (0 = unlimited). | |
| daily_tokens_used | int64 | daily_tokens_used is the tokens consumed today. | |
| monthly_tokens_used | int64 | monthly_tokens_used is the tokens consumed this month. | |
| daily_cost_used | double | daily_cost_used is the cost incurred today in USD. | |
| monthly_cost_used | double | monthly_cost_used is the cost incurred this month in USD. | |
| status_color | string | status_color is a denormalised UI signal: "green" (well under cap), "amber" (>= 75% of any cap), or "red" (>= cap). Computed on the server from the same {used, cap} pairs so the client never has to re-derive the threshold. Empty when no row exists in agent_budgets (the agent has not had a budget configured yet). |
CreateAgentRequest
CreateAgentRequest provisions a new agent within the caller's scope.
| Field | Type | Label | Description |
|---|---|---|---|
| pillar_id | string | pillar_id is the OPTIONAL business unit to create the agent in. Empty for agents on root teams, which have no pillar (uniform team graph, #1851). | |
| team_id | string | team_id is the team to create the agent in. | |
| name | string | name is the human-readable agent name. | |
| clearance | int32 | clearance is the agent's clearance level (1-5). | |
| persona | string | persona is the optional initial persona text. | |
| model_id | string | model_id is the optional LLM model identifier; defaults to "claude-sonnet-4-20250514". | |
| tools | string | tools is the optional initial per-agent MCP allowlist: a JSON array of mcp_servers UUIDs that NARROWS the agent's team-resolved MCP set (ADR-0022 W3/B8, #1744). Empty/absent = inherit ALL team MCP servers. REPURPOSED from the legacy tool-definitions array. |
CreateAgentResponse
CreateAgentResponse confirms agent creation.
| Field | Type | Label | Description |
|---|---|---|---|
| agent | Agent | agent is the newly created agent record. | |
| configuration | AgentConfiguration | configuration is the initial agent configuration. |
DeleteAgentRequest
DeleteAgentRequest soft-deletes an agent by ID.
| Field | Type | Label | Description |
|---|---|---|---|
| agent_id | string | agent_id is the UUID of the agent to soft-delete. |
DeleteAgentResponse
DeleteAgentResponse confirms the soft deletion.
| Field | Type | Label | Description |
|---|---|---|---|
| deleted_at | google.protobuf.Timestamp | deleted_at is the timestamp when the agent was marked as deleted. |
DeployAgentToTeamRequest
DeployAgentToTeamRequest assigns an agent to a team.
| Field | Type | Label | Description |
|---|---|---|---|
| agent_id | string | agent_id is the UUID of the agent. | |
| team_id | string | team_id is the UUID of the target team. |
DeployAgentToTeamResponse
DeployAgentToTeamResponse confirms the deployment.
| Field | Type | Label | Description |
|---|---|---|---|
| agent | Agent | agent is the updated agent record. | |
| deployed_at | google.protobuf.Timestamp | deployed_at is the timestamp of the deployment. |
DeployFromTemplateBudget
DeployFromTemplateBudget carries the budget caps for the wizard's budget step. Fields mirror SetBudgetCapRequest.
| Field | Type | Label | Description |
|---|---|---|---|
| daily_token_cap | int64 | daily_token_cap is the daily token limit (0 = unlimited). | |
| monthly_token_cap | int64 | monthly_token_cap is the monthly token limit (0 = unlimited). | |
| daily_cost_cap | double | daily_cost_cap is the daily cost limit in USD (0.0 = unlimited). | |
| monthly_cost_cap | double | monthly_cost_cap is the monthly cost limit in USD (0.0 = unlimited). |
DeployFromTemplateRequest
DeployFromTemplateRequest is the one-shot wizard commit. All fields are validated up front; on any failure the caller receives a single errdetails.BadRequest with FieldViolations pointing at the specific fields that need correction (LLD-4 §2.1 pattern). The composite is transactional — every sub-step (RegisterAgent + DeployAgentToTeam + SetBudgetCap + SetAutonomyLevel) commits atomically.
| Field | Type | Label | Description |
|---|---|---|---|
| template_id | string | template_id selects a row from ListAgentTemplates. Required. | |
| name | string | name is the human-readable agent name. Required. | |
| role | string | role is the free-text role tag rendered on the agent card (e.g. "Customer Support Tier-1"). Optional. | |
| reports_to | string | reports_to is the supervising member UUID — drives the inferred clearance via MemberService.InferAgentClearance. Required. | |
| team_id | string | team_id is the destination team (= org_unit of unit_type='team'). Required. | |
| pillar_id | string | pillar_id is the team's parent pillar — required by the legacy RegisterAgent contract until org-units fully replaces it. | |
| clearance | int32 | clearance is the agent's clearance level (1..5). The wizard pre-fills this from InferAgentClearance but the caller may override. Final value is still constrained by the supervising member's clearance via the existing CreateMember invariant. | |
| autonomy | AutonomyLevel | autonomy is the governance autonomy level the wizard's slider selects. Required. | |
| approval_template | string | approval_template is the JSON approval-template required when autonomy crosses the governance-review threshold. Optional otherwise. | |
| budget | DeployFromTemplateBudget | budget carries the daily/monthly token + cost caps from the wizard's budget step. | |
| guardrail_ids | string | repeated | guardrail_ids is the optional list of guardrail UUIDs to attach. Empty = no guardrails. Currently a forward-looking seam — the composite records the IDs in the lifecycle event metadata so the governance worker can pick them up; the actual attach RPC lives on a separate service (GAP-39, future). |
| model_id | string | model_id is the LLM model id; defaults to the platform default (claude-sonnet-4-20250514) when empty. | |
| persona | string | persona is the optional system prompt; the wizard synthesises one from default_actions when empty. | |
| tools | string | tools is the optional per-agent MCP allowlist: a JSON array of mcp_servers UUIDs that NARROWS the agent's team-resolved MCP set (ADR-0022 W3/B8, #1744). Empty/absent = inherit ALL team MCP servers; the wizard supplies an empty array when none are deselected. REPURPOSED from the legacy tool-definitions array. The wizard CANNOT grant — grants stay team-level. |
DeployFromTemplateResponse
DeployFromTemplateResponse returns the new agent's identity. Callers can fetch the full record via GetAgent if they need the persona / tools / budget back.
| Field | Type | Label | Description |
|---|---|---|---|
| agent_id | string | agent_id is the UUID of the newly-deployed agent. | |
| created_at | google.protobuf.Timestamp | created_at is the timestamp the agent row was inserted. | |
| applied_clearance | int32 | applied_clearance is the final clearance level persisted on the agent — surfaced so the wizard can render the "applied X (capped by manager)" hint without a follow-up call. |
GetAgentHealthRequest
GetAgentHealthRequest reads real-time health signals for an agent.
| Field | Type | Label | Description |
|---|---|---|---|
| agent_id | string | agent_id is the UUID of the agent. |
GetAgentHealthResponse
GetAgentHealthResponse returns real-time health data.
| Field | Type | Label | Description |
|---|---|---|---|
| status | string | status is the derived health status: "healthy", "degraded", "down", or "idle". | |
| last_active | google.protobuf.Timestamp | last_active is the timestamp of the agent's most recent action. | |
| error_rate | double | error_rate is the percentage of errors in the recent window (0-100). | |
| queue_depth | int64 | queue_depth is the number of pending items in the agent's work queue. | |
| tokens_used_24h | int64 | tokens_used_24h is the total tokens consumed in the last 24 hours. |
GetAgentRequest
GetAgentRequest retrieves a single agent by ID.
| Field | Type | Label | Description |
|---|---|---|---|
| agent_id | string | agent_id is the UUID of the agent to retrieve. |
GetAgentResponse
GetAgentResponse returns the agent and its configuration.
| Field | Type | Label | Description |
|---|---|---|---|
| agent | Agent | agent is the retrieved agent record. | |
| configuration | AgentConfiguration | configuration is the agent's current configuration. |
GetBudgetStatusRequest
GetBudgetStatusRequest retrieves current-period usage vs caps.
| Field | Type | Label | Description |
|---|---|---|---|
| agent_id | string | agent_id is the UUID of the agent. |
GetBudgetStatusResponse
GetBudgetStatusResponse returns current usage and caps.
| Field | Type | Label | Description |
|---|---|---|---|
| daily_token_cap | int64 | daily_token_cap is the configured daily token limit. | |
| monthly_token_cap | int64 | monthly_token_cap is the configured monthly token limit. | |
| daily_cost_cap | double | daily_cost_cap is the configured daily cost limit in USD. | |
| monthly_cost_cap | double | monthly_cost_cap is the configured monthly cost limit in USD. | |
| daily_tokens_used | int64 | daily_tokens_used is the tokens consumed today. | |
| monthly_tokens_used | int64 | monthly_tokens_used is the tokens consumed this month. | |
| daily_cost_used | double | daily_cost_used is the cost incurred today in USD. | |
| monthly_cost_used | double | monthly_cost_used is the cost incurred this month in USD. | |
| period_start | google.protobuf.Timestamp | period_start is the start of the current billing period. |
ListAgentRow
ListAgentRow is the rich shape returned by ListAgents — the bare
agents repeated field is preserved for backwards compatibility, but
new clients should consume rows instead. GAP-21 + GAP-36 (#1084).
| Field | Type | Label | Description |
|---|---|---|---|
| agent | Agent | agent is the canonical Agent record. | |
| budget | BudgetStatus | budget is the inline budget snapshot (avoids N+1 GetBudgetStatus calls on the directory page). Nil when no row exists in agent_budgets. | |
| owner_human_id | string | owner_human_id is the UUID of the supervising human member — resolved by walking the agent's member row up the reports_to chain to the first MEMBER_TYPE_HUMAN ancestor. Empty when the agent has no associated member row (legacy headless agents pre-migration 058) or when no human ancestor exists in the chain. | |
| owner_human_name | string | owner_human_name is the denormalised display_name of owner_human_id, surfaced inline so the directory does not need a second round-trip per row. | |
| last_action_at | google.protobuf.Timestamp | last_action_at is the timestamp of the agent's most recent recorded action — sourced from Redis (agent:<id>:last_active). Nil when no activity has ever been observed. | |
| actions_24h | int64 | actions_24h is the cardinality of distinct actions observed in the last 24 hours, sourced from Redis (agent:<id>:actions). | |
| team_deleted | bool | team_deleted is true when the agent's team_id references an org_unit that no longer resolves to a LIVE team (soft-deleted or nonexistent). Integrity #1813: migration 070 dropped the agents.team_id FK, so an agent can outlive the team it was bound to and be silently orphaned onto a tombstone. The directory MUST render these as "team deleted / unassigned" rather than resolving the tombstone's name as if live. False for agents with a NULL/empty team_id (legitimately org-wide / headless) and for agents bound to a live team. |
ListAgentTemplatesRequest
ListAgentTemplatesRequest is empty for v1 (no filters yet).
ListAgentTemplatesResponse
ListAgentTemplatesResponse returns the static template catalog.
| Field | Type | Label | Description |
|---|---|---|---|
| templates | AgentTemplate | repeated | templates is the ordered prototype-template catalog. |
ListAgentsRequest
ListAgentsRequest returns a paginated list of active agents.
All filter fields are optional and AND-combined. Legacy callers passing only pillar_id / team_id retain the original behaviour; new filters default to "no filter" so the response shape is unchanged when none are set.
| Field | Type | Label | Description |
|---|---|---|---|
| pillar_id | string | pillar_id optionally filters agents by business unit. | |
| team_id | string | team_id optionally filters agents by team. | |
| page | int32 | page is the 1-based page number for pagination. | |
| page_size | int32 | page_size is the maximum number of results per page. Max 100, default 20. | |
| clearance_filter | int32 | clearance_filter restricts results to a specific clearance level (1..5). 0 = no filter. GAP-35 (#1084). | |
| autonomy_filter | AutonomyLevel | autonomy_filter restricts results to a specific autonomy level. AUTONOMY_LEVEL_UNSPECIFIED = no filter. GAP-35. | |
| status_filter | string | status_filter restricts results to a specific status — "active" or "paused". Empty = no filter. GAP-35. | |
| health_filter | HealthFilter | health_filter restricts results to a derived health bucket; see HealthFilter for semantics. GAP-35. |
Implementation note for callers: OVER_BUDGET and UNDER_UTILIZED are applied as SQL predicates so total_count and the returned page are both filter-aware. RECENTLY_FAILING is a POST-FETCH filter applied in process against Redis-derived health state — the SQL layer returns the unfiltered page, then rows that don't match the recently-failing bucket are dropped before responding. As a result, the page size for a RECENTLY_FAILING request may shrink below page_size and total_count remains the pre-filter SQL count (the upper bound). See ListAgentsResponse.total_count for matching semantics on the response side. | | query | string | | query is a free-text substring matched case-insensitively against the agent name. Empty = no filter. GAP-35. |
ListAgentsResponse
ListAgentsResponse returns a paginated list of agents.
| Field | Type | Label | Description |
|---|---|---|---|
| agents | Agent | repeated | agents is the list of agent records (legacy field — kept for backwards compatibility with pre-redesign clients). |
| total_count | int32 | total_count is the total number of matching agents (for pagination). For OVER_BUDGET and UNDER_UTILIZED this reflects the SQL-side filtered count (matches the page size). For HEALTH_FILTER_RECENTLY_FAILING this is the pre-filter SQL count — an upper bound — because that bucket is computed post-fetch from Redis state; the rows / agents arrays may be shorter than the count for that filter only. | |
| rows | ListAgentRow | repeated | rows is the rich-shape list with budget inline + row metadata. New clients should consume this and ignore agents. GAP-21 + GAP-36. |
PauseAgentRequest
PauseAgentRequest transitions an agent to status=paused.
| Field | Type | Label | Description |
|---|---|---|---|
| agent_id | string | agent_id is the UUID of the agent to pause. |
PauseAgentResponse
PauseAgentResponse confirms the pause.
| Field | Type | Label | Description |
|---|---|---|---|
| agent | Agent | agent is the updated agent record (status=paused). | |
| already_paused | bool | already_paused is true if the agent was already paused (idempotent no-op — no lifecycle event was emitted). |
RegisterAgentRequest
RegisterAgentRequest creates a headless agent with full configuration.
| Field | Type | Label | Description |
|---|---|---|---|
| pillar_id | string | pillar_id is the OPTIONAL business unit UUID. Empty for agents on root teams, which have no pillar (uniform team graph, #1851). | |
| team_id | string | team_id is the team UUID. | |
| name | string | name is the human-readable agent name. | |
| clearance | int32 | clearance is the agent's clearance level (1-5). | |
| persona | string | persona is the system prompt text (max 32000 chars). | |
| model_id | string | model_id is the LLM model id; defaults to claude-sonnet-4-20250514. | |
| tools | string | tools is the per-agent MCP allowlist: a JSON array of mcp_servers UUIDs that NARROWS this agent's team-resolved MCP set (ADR-0022 W3/B8, #1744). Empty/absent = inherit ALL of the team's approved MCP servers. It can only DESELECT — an id absent from the team set has no effect (never a grant). REPURPOSED from the legacy "JSON array of tool definitions": the legacy static-list read is BYPASSED by the Org Model v2.4 resolver, so no behaviour regression. Enforced at session freeze (freezeResolvedTools). | |
| autonomy_level | AutonomyLevel | autonomy_level is the governance mode. | |
| runtime | string | runtime selects the worker executor: "langgraph" (default) | |
| llm_base_url | string | llm_base_url is an optional Anthropic-format endpoint for the claude_sdk runtime. Only valid when runtime == "claude_sdk". Added in #1631. |
RegisterAgentResponse
RegisterAgentResponse confirms headless agent creation.
| Field | Type | Label | Description |
|---|---|---|---|
| agent | Agent | agent is the newly created agent record. | |
| configuration | AgentConfiguration | configuration is the initial agent configuration. |
RegisterExternalAgentRequest
RegisterExternalAgentRequest registers a BYO agent and issues its credential. It provisions a first-class agent (runtime="external") governed identically to an internal agent (team, clearance, per-agent MCP allowlist, audit), then records the register-once credential→agent binding in external_agent_clients.
| Field | Type | Label | Description |
|---|---|---|---|
| pillar_id | string | pillar_id is the OPTIONAL business unit UUID. Empty for root-team agents. | |
| team_id | string | team_id is the team UUID; it is also the agent's unit_id (the token audience /mcp/team/{unit}). Required. | |
| name | string | name is the human-readable agent name. Required. | |
| clearance | int32 | clearance is the agent's clearance level (1-5). Required. | |
| persona | string | persona is the optional system prompt text (max 32000 chars). | |
| model_id | string | model_id is the optional LLM model id; defaults to claude-sonnet-4-20250514. | |
| tools | string | tools is the optional per-agent MCP allowlist: a JSON array of mcp_servers UUIDs that NARROWS the agent's team-resolved MCP set (ADR-0022 W3/B8). Empty = inherit ALL team MCP servers. | |
| autonomy_level | AutonomyLevel | autonomy_level is the optional governance mode. | |
| public_key_jwk | string | public_key_jwk is the customer's PUBLIC key as a JWK JSON object (the PREFERRED private_key_jwt path). When set, NO shared secret is generated and client_secret is empty in the response. When empty, the server generates a shared secret and returns it ONCE. Exactly one credential is issued. |
RegisterExternalAgentResponse
RegisterExternalAgentResponse returns the new agent + its client credential.
| Field | Type | Label | Description |
|---|---|---|---|
| agent | Agent | agent is the newly created external agent record. | |
| configuration | AgentConfiguration | configuration is the initial agent configuration (runtime="external"). | |
| client_id | string | client_id is the server-generated credential handle the external agent presents to the token endpoint (PR-4). Stable for the life of the binding. | |
| client_secret | string | client_secret is the server-generated shared secret, returned EXACTLY ONCE. Populated ONLY for EXTERNAL_CREDENTIAL_TYPE_SHARED_SECRET; empty for the public-key path. It is never persisted in plaintext or logged. | |
| credential_type | ExternalCredentialType | credential_type indicates how the agent authenticates (public key vs secret). |
ResumeAgentRequest
ResumeAgentRequest transitions an agent back to status=active.
| Field | Type | Label | Description |
|---|---|---|---|
| agent_id | string | agent_id is the UUID of the agent to resume. |
ResumeAgentResponse
ResumeAgentResponse confirms the resume.
| Field | Type | Label | Description |
|---|---|---|---|
| agent | Agent | agent is the updated agent record (status=active). | |
| already_active | bool | already_active is true if the agent was already active (idempotent no-op — no lifecycle event was emitted). |
RevokeExternalAgentCredentialRequest
RevokeExternalAgentCredentialRequest disables a client credential.
| Field | Type | Label | Description |
|---|---|---|---|
| client_id | string | client_id identifies the credential to revoke. Required. Org-scoped. |
RevokeExternalAgentCredentialResponse
RevokeExternalAgentCredentialResponse confirms the revocation.
| Field | Type | Label | Description |
|---|---|---|---|
| revoked_at | google.protobuf.Timestamp | revoked_at is the timestamp the credential was disabled. The agent is refused at its next token refresh (<=10 min). |
RotateExternalAgentCredentialRequest
RotateExternalAgentCredentialRequest rotates a client's credential in place.
| Field | Type | Label | Description |
|---|---|---|---|
| client_id | string | client_id identifies the credential to rotate. Required. Scoped to the caller's org (an explicit org_id predicate enforces ownership). | |
| public_key_jwk | string | public_key_jwk, when set, replaces the stored public key (private_key_jwt path). When empty, the server generates a NEW shared secret and returns it ONCE. The client_id and agent binding are unchanged; rotated_at is stamped. |
RotateExternalAgentCredentialResponse
RotateExternalAgentCredentialResponse returns the post-rotation credential.
| Field | Type | Label | Description |
|---|---|---|---|
| client_id | string | client_id is unchanged (rotation reuses the binding). | |
| client_secret | string | client_secret is the newly-generated shared secret, returned EXACTLY ONCE. Populated ONLY for the shared-secret path; empty for the public-key path. | |
| credential_type | ExternalCredentialType | credential_type indicates the post-rotation credential shape. | |
| rotated_at | google.protobuf.Timestamp | rotated_at is the timestamp the rotation was recorded. |
SetAgentPersonaRequest
SetAgentPersonaRequest updates the persona text for an agent.
| Field | Type | Label | Description |
|---|---|---|---|
| agent_id | string | agent_id is the UUID of the agent. | |
| persona | string | persona is the new persona text (max 32000 characters). |
SetAgentPersonaResponse
SetAgentPersonaResponse confirms the persona update.
| Field | Type | Label | Description |
|---|---|---|---|
| updated_at | google.protobuf.Timestamp | updated_at is the timestamp of the update. |
SetAgentToolsRequest
SetAgentToolsRequest replaces the agent's per-agent MCP allowlist.
| Field | Type | Label | Description |
|---|---|---|---|
| agent_id | string | agent_id is the UUID of the agent. | |
| tools | string | tools is the per-agent MCP allowlist: a JSON array of mcp_servers UUIDs that NARROWS the agent's team-resolved MCP set (ADR-0022 W3/B8, #1744). Empty array = clear the allowlist / inherit ALL team MCP servers. Every id must be a live MCP server owned by the caller's tenant. REPURPOSED from the legacy tool-definitions array. |
SetAgentToolsResponse
SetAgentToolsResponse confirms the tools update.
| Field | Type | Label | Description |
|---|---|---|---|
| updated_at | google.protobuf.Timestamp | updated_at is the timestamp of the update. |
SetAutonomyLevelRequest
SetAutonomyLevelRequest configures agent governance autonomy.
| Field | Type | Label | Description |
|---|---|---|---|
| agent_id | string | agent_id is the UUID of the agent. | |
| autonomy_level | AutonomyLevel | autonomy_level is the new governance level. | |
| approval_template | string | approval_template is an optional JSON approval template (for supervised/semi). |
SetAutonomyLevelResponse
SetAutonomyLevelResponse confirms the autonomy level update.
| Field | Type | Label | Description |
|---|---|---|---|
| updated_at | google.protobuf.Timestamp | updated_at is the timestamp of the update. |
SetBudgetCapRequest
SetBudgetCapRequest sets daily/monthly token and cost limits.
| Field | Type | Label | Description |
|---|---|---|---|
| agent_id | string | agent_id is the UUID of the agent. | |
| daily_token_cap | int64 | daily_token_cap is the daily token limit (0 = unlimited). | |
| monthly_token_cap | int64 | monthly_token_cap is the monthly token limit (0 = unlimited). | |
| daily_cost_cap | double | daily_cost_cap is the daily cost limit in USD (0.0 = unlimited). | |
| monthly_cost_cap | double | monthly_cost_cap is the monthly cost limit in USD (0.0 = unlimited). |
SetBudgetCapResponse
SetBudgetCapResponse confirms the budget cap update.
| Field | Type | Label | Description |
|---|---|---|---|
| updated_at | google.protobuf.Timestamp | updated_at is the timestamp of the update. |
UpdateAgentRequest
UpdateAgentRequest modifies mutable agent fields.
| Field | Type | Label | Description |
|---|---|---|---|
| agent_id | string | agent_id is the UUID of the agent to update. | |
| name | string | name is the new agent name (ignored if empty). | |
| clearance | int32 | clearance is the new clearance level (ignored if zero). |
UpdateAgentResponse
UpdateAgentResponse returns the updated agent.
| Field | Type | Label | Description |
|---|---|---|---|
| agent | Agent | agent is the updated agent record. |
AutonomyLevel
AutonomyLevel controls agent self-governance.
| Name | Number | Description |
|---|---|---|
| AUTONOMY_LEVEL_UNSPECIFIED | 0 | AUTONOMY_LEVEL_UNSPECIFIED is the default zero value. |
| AUTONOMY_LEVEL_SUPERVISED | 1 | AUTONOMY_LEVEL_SUPERVISED means every action requires approval. |
| AUTONOMY_LEVEL_SEMI_AUTONOMOUS | 2 | AUTONOMY_LEVEL_SEMI_AUTONOMOUS means only escalations need approval. |
| AUTONOMY_LEVEL_AUTONOMOUS | 3 | AUTONOMY_LEVEL_AUTONOMOUS means no approval required. |
ExternalCredentialType
ExternalCredentialType names how an external agent authenticates to the platform token endpoint (PR-4). It is DERIVED from which credential material is stored (public key XOR shared secret) — the server sets it on responses so the caller knows which secret handling applies.
| Name | Number | Description |
|---|---|---|
| EXTERNAL_CREDENTIAL_TYPE_UNSPECIFIED | 0 | EXTERNAL_CREDENTIAL_TYPE_UNSPECIFIED is the zero value; never persisted. |
| EXTERNAL_CREDENTIAL_TYPE_PUBLIC_KEY_JWT | 1 | EXTERNAL_CREDENTIAL_TYPE_PUBLIC_KEY_JWT is the PREFERRED path: the customer holds the private key and registered only the public JWK. Nothing secret is returned — the customer already holds the key. |
| EXTERNAL_CREDENTIAL_TYPE_SHARED_SECRET | 2 | EXTERNAL_CREDENTIAL_TYPE_SHARED_SECRET is the FALLBACK: the server generated a shared secret, returned EXACTLY ONCE in client_secret, and persisted only as a bcrypt hash. |
HealthFilter
HealthFilter classifies an agent by a derived runtime-health bucket. GAP-35 (#1084).
| Name | Number | Description |
|---|---|---|
| HEALTH_FILTER_UNSPECIFIED | 0 | HEALTH_FILTER_UNSPECIFIED disables the health filter (returns all health buckets). |
| HEALTH_FILTER_OVER_BUDGET | 1 | HEALTH_FILTER_OVER_BUDGET keeps agents whose daily token / cost usage is at or above the configured cap (treats unset cap = 0 as "no cap" and excludes the row from this bucket). |
| HEALTH_FILTER_UNDER_UTILIZED | 2 | HEALTH_FILTER_UNDER_UTILIZED keeps agents that have been provisioned for more than 7 days and have zero tokens consumed today — useful for spotting deployed-but-unused agents. |
| HEALTH_FILTER_RECENTLY_FAILING | 3 | HEALTH_FILTER_RECENTLY_FAILING keeps agents whose recent error rate crosses the GetAgentHealth "degraded"/"down" threshold. Implemented as a Redis-side post-filter on the page rather than a SQL predicate — agents that match are kept; non-matches are dropped from the returned page (page_size may collapse). The total_count still reflects the pre-filter SQL row count so the caller knows the upper bound. |
AgentService
AgentService manages the lifecycle, configuration, and health of AI agents within the UpsQuad platform. All operations are scoped to a tenant organisation via JWT-derived scope claims.
| Method Name | Request Type | Response Type | Description |
|---|---|---|---|
| CreateAgent | CreateAgentRequest | CreateAgentResponse | CreateAgent provisions a new agent within a team, subject to the organisation's max_agents feature gate. |
| GetAgent | GetAgentRequest | GetAgentResponse | GetAgent retrieves a single agent by ID, excluding soft-deleted agents. |
| UpdateAgent | UpdateAgentRequest | UpdateAgentResponse | UpdateAgent modifies mutable agent fields (name, clearance). |
| DeleteAgent | DeleteAgentRequest | DeleteAgentResponse | DeleteAgent performs a soft delete by setting the deleted_at timestamp. Associated agent_configurations are NOT deleted. |
| ListAgents | ListAgentsRequest | ListAgentsResponse | ListAgents returns a paginated list of active agents, optionally filtered by pillar_id and/or team_id. |
| SetAgentPersona | SetAgentPersonaRequest | SetAgentPersonaResponse | SetAgentPersona updates the persona text in agent_configurations. Maximum 32000 characters. |
| SetAgentTools | SetAgentToolsRequest | SetAgentToolsResponse | SetAgentTools replaces the agent's per-agent MCP allowlist (the repurposed agent_configurations.tools JSONB — see the field docs). Narrow-only; gated on the L4-OR-team-Manager clearance matrix and a per-id tenant IDOR check (ADR-0022 W3/B8, #1744). |
| GetAgentHealth | GetAgentHealthRequest | GetAgentHealthResponse | GetAgentHealth reads real-time health signals from Redis and derives an overall health status (healthy, degraded, down, idle). |
| RegisterAgent | RegisterAgentRequest | RegisterAgentResponse | RegisterAgent creates a headless (API-provisioned) agent with clearance, persona, model, tools, and optional autonomy level. |
| SetAutonomyLevel | SetAutonomyLevelRequest | SetAutonomyLevelResponse | SetAutonomyLevel configures the agent's governance autonomy. |
| SetBudgetCap | SetBudgetCapRequest | SetBudgetCapResponse | SetBudgetCap sets daily/monthly token and cost limits. |
| GetBudgetStatus | GetBudgetStatusRequest | GetBudgetStatusResponse | GetBudgetStatus returns current-period usage vs caps. |
| DeployAgentToTeam | DeployAgentToTeamRequest | DeployAgentToTeamResponse | DeployAgentToTeam assigns agent to team, wires governance, starts heartbeat. |
| PauseAgent | PauseAgentRequest | PauseAgentResponse | PauseAgent transitions the agent to status=paused. Idempotent: calling on an already-paused agent returns the current row without re-emitting a lifecycle event. GAP-37 (#1085). |
| ResumeAgent | ResumeAgentRequest | ResumeAgentResponse | ResumeAgent transitions the agent back to status=active. Idempotent. GAP-37 (#1085). |
| ListAgentTemplates | ListAgentTemplatesRequest | ListAgentTemplatesResponse | ListAgentTemplates returns the prototype-template catalog backing step 1 of the redesigned 4-step Deploy wizard. Static-ish per release; no per-tenant authoring surface yet. GAP-38 (#1086). |
| DeployFromTemplate | DeployFromTemplateRequest | DeployFromTemplateResponse | DeployFromTemplate is the one-shot wizard commit: equivalent to RegisterAgent + DeployAgentToTeam + SetBudgetCap + SetAutonomyLevel (+ guardrail attach) in a single transaction with rollback. The wizard never lands a half-deployed agent — every step succeeds or none of them do. GAP-41 (#1088). |
| RegisterExternalAgent | RegisterExternalAgentRequest | RegisterExternalAgentResponse | RegisterExternalAgent registers an externally-hosted (BYO) agent as a first-class agent (runtime="external") AND issues its client credential in one transaction — #1864 trust-root PR-3 (#1956). The external agent later presents the credential to the platform token endpoint (PR-4) and receives the SAME agent-scoped gateway token an internal mint produces. Preferred credential is a customer-supplied public key (private_key_jwt); the fallback is a server-generated shared secret returned EXACTLY ONCE in the response. |
| RotateExternalAgentCredential | RotateExternalAgentCredentialRequest | RotateExternalAgentCredentialResponse | RotateExternalAgentCredential rotates an external agent's public key or shared secret, keeping the client_id and the agent binding stable (rotated_at is stamped). A newly-generated secret is returned ONCE. #1956. |
| RevokeExternalAgentCredential | RevokeExternalAgentCredentialRequest | RevokeExternalAgentCredentialResponse | RevokeExternalAgentCredential disables an external agent's credential (revoked_at is set). The agent is refused at its next token refresh (<=10 min) at the PR-4 endpoint. #1956. |
Scalar Value Types
| .proto Type | Notes | C++ | Java | Python | Go | C# | PHP | Ruby |
|---|---|---|---|---|---|---|---|---|
| double | double | double | float | float64 | double | float | Float | |
| float | float | float | float | float32 | float | float | Float | |
| int32 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| int64 | Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| uint32 | Uses variable-length encoding. | uint32 | int | int/long | uint32 | uint | integer | Bignum or Fixnum (as required) |
| uint64 | Uses variable-length encoding. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum or Fixnum (as required) |
| sint32 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| sint64 | Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| fixed32 | Always four bytes. More efficient than uint32 if values are often greater than 2^28. | uint32 | int | int | uint32 | uint | integer | Bignum or Fixnum (as required) |
| fixed64 | Always eight bytes. More efficient than uint64 if values are often greater than 2^56. | uint64 | long | int/long | uint64 | ulong | integer/string | Bignum |
| sfixed32 | Always four bytes. | int32 | int | int | int32 | int | integer | Bignum or Fixnum (as required) |
| sfixed64 | Always eight bytes. | int64 | long | int/long | int64 | long | integer/string | Bignum |
| bool | bool | boolean | boolean | bool | bool | boolean | TrueClass/FalseClass | |
| string | A string must always contain UTF-8 encoded or 7-bit ASCII text. | string | String | str/unicode | string | string | string | String (UTF-8) |
| bytes | May contain any arbitrary sequence of bytes. | string | ByteString | str | []byte | ByteString | string | String (ASCII-8BIT) |