Tiyi v3.8.0

ai.proto — AI copilot and advisory proposals

Schema: tiyi.v1 · ai.proto · English guide · 中文指南 · Full RPC index

Services

AIService

Read/advisory (require ai:read).

RPC Kind Required permission
ListAIProposals unary (ai:read)
GetAIProposal unary (ai:read)
GetAIStatus unary (ai:read)
DraftCustomRule unary (ai:propose)
TranslateLogQuery unary (ai:read)
StreamAnalysis server stream ai:read and log:read
StreamChat server stream ai:read and log:read
ApplyAIProposal unary (ai:apply)
RejectAIProposal unary (ai:propose)
SetAIProviderSecret unary (system:write)

RPCs

AIService.ListAIProposals

Request — tiyi.v1.ListAIProposalsRequest

Field JSON key Type Cardinality Description
page page CursorRequest singular —
status status AIProposalStatus singular optional filter; UNSPECIFIED = any

Response — tiyi.v1.ListAIProposalsResponse

Field JSON key Type Cardinality Description
items items AIProposal repeated —
page page CursorResponse singular —

AIService.GetAIProposal

Request — tiyi.v1.GetAIProposalRequest

Field JSON key Type Cardinality Description
id id string singular —

Response — tiyi.v1.GetAIProposalResponse

Field JSON key Type Cardinality Description
proposal proposal AIProposal singular —

AIService.GetAIStatus

GetAIStatus reports whether the layer is enabled/configured and the worker counters — drives the UI "AI Advisor" availability banner.

Request — tiyi.v1.GetAIStatusRequest

No fields — send {}.

Response — tiyi.v1.GetAIStatusResponse

Field JSON key Type Cardinality Description
enabled enabled bool singular ai.enabled
configured configured bool singular provider + model + key all set
provider provider string singular openai_compatible | azure_openai | disabled
model_summary modelSummary string singular —

AIService.DraftCustomRule

Proposal generation (require ai:propose). Returns drafts; mutates nothing. The generated proposal is stored as a draft ai_proposal the operator later applies through ApplyAIProposal.

Request — tiyi.v1.DraftCustomRuleRequest

Field JSON key Type Cardinality Description
intent intent string singular intent is the operator's natural-language description / CVE / threat intel ("block requests with X-Debug header to /admin").
policy_id policyId string singular —

Response — tiyi.v1.DraftCustomRuleResponse

Field JSON key Type Cardinality Description
proposal proposal AIProposal singular proposal is a stored draft of kind CUSTOM_RULE (patch carries the visualrule.Spec JSON). Apply it via ApplyAIProposal.
seclang_preview seclangPreview string singular seclang_preview is the compiled SecLang for the drafted rule. Every generated rule starts LOG-ONLY / canary (action=log), so the preview never blocks until the operator promotes it.
warnings warnings string repeated —

AIService.TranslateLogQuery

Read/advisory (require ai:read). NL->typed query never emits raw SQL.

Request — tiyi.v1.TranslateLogQueryRequest

Field JSON key Type Cardinality Description
query query string singular e.g. "SQLi from CN in the last 6h that weren't blocked"

Response — tiyi.v1.TranslateLogQueryResponse

Field JSON key Type Cardinality Description
query query SecurityEventQuery singular —
notes notes string singular notes carries any caveat the translator wants surfaced (e.g. a term it could not map to a typed field).

AIService.StreamAnalysis

StreamAnalysis streams a plain-text (markdown) explanation for one subject: a single retained log event or the current log table. Advisory only; it never mutates state. Requires ai:read (middleware) AND the subject's log:read permission, enforced in the handler so it can never be a side channel to logs. Provider deltas are forwarded as chunks; the final chunk sets done=true + token_cost. The call is bound by the shared rate limit, an input cap, and ai.timeout; a client disconnect cancels the provider call (docs/design/ai-copilot-analysis.md).

Request — tiyi.v1.StreamAnalysisRequest

Field JSON key Type Cardinality Description
log_event logEvent LogEventRef singular Part of oneof subject.
log_table logTable LogTable singular Part of oneof subject.

Response — tiyi.v1.StreamAnalysisResponse

Field JSON key Type Cardinality Description
delta delta string singular —
done done bool singular —
token_cost tokenCost int64 singular JSON string (64-bit ints are quoted).

AIService.StreamChat

StreamChat is the conversational Copilot ability: a free-talk, multi-turn assistant that answers open-ended operator questions by driving the EXISTING log query/filter/summary capabilities itself (docs/design/ai-copilot-analysis.md § Chat agent). It adds NO new log query surface — the model calls read-only tools that are thin in-process wrappers over the same tenant-scoped queries the Log pages already use (security/access summaries + filtered event lookups + site resolution), then summarizes the results to answer questions like "top 10 attackers in the last hour", "is 1.1.1.5 evil?", or "was www.test.com attacked today, from which IP and what attack type?". The server is stateless: the client replays prior turns in history and appends the new message. Advisory only — every tool is read-only and tenant-scoped; the model never mutates state and never blocks traffic. Requires ai:read (middleware) AND log:read (enforced in the handler, since every tool reads logs — same dual-RBAC backstop as StreamAnalysis). The call is bound by the shared rate limit, a per-turn tool-step cap, and ai.timeout; a client disconnect cancels the in-flight provider call.

Request — tiyi.v1.StreamChatRequest

Field JSON key Type Cardinality Description
history history ChatTurn repeated history is the prior conversation (oldest first), capped server-side.
message message string singular message is the new operator question (free text).
site_id siteId string singular site_id is an optional UI scope hint (the site the operator is currently viewing); the model may use it to bias tool calls but can still ask about any tenant-visible site.

Response — tiyi.v1.StreamChatResponse

Field JSON key Type Cardinality Description
delta delta string singular —
done done bool singular —
token_cost tokenCost int64 singular JSON string (64-bit ints are quoted).
tool_activity toolActivity string singular —

AIService.ApplyAIProposal

Apply (require ai:apply). Validates the typed patch, then calls an AUDITED mutation service (UpsertRuleOverride today) and writes a normal audit_event. Rejects any free-form patch and any unsupported proposal kind.

Request — tiyi.v1.ApplyAIProposalRequest

Field JSON key Type Cardinality Description
id id string singular —

Response — tiyi.v1.ApplyAIProposalResponse

Field JSON key Type Cardinality Description
proposal proposal AIProposal singular updated to ACCEPTED with applied_audit_id
result result MutationResult singular the underlying audited mutation result

AIService.RejectAIProposal

RejectAIProposal marks a draft proposal rejected (operator dismissal).

Request — tiyi.v1.RejectAIProposalRequest

Field JSON key Type Cardinality Description
id id string singular —

Response — tiyi.v1.RejectAIProposalResponse

Field JSON key Type Cardinality Description
proposal proposal AIProposal singular —

AIService.SetAIProviderSecret

SetAIProviderSecret stores the provider API key under the shared KEK/DEK envelope (requires system:write — the key is the secret half of the ai.* provider config set via SystemService.UpdateSystemSettings). The key is write-only: it is never returned by any RPC. An empty value is a no-op that preserves the stored key.

Request — tiyi.v1.SetAIProviderSecretRequest

Field JSON key Type Cardinality Description
api_key apiKey string singular write-only; empty = no-op (preserve stored key)

Response — tiyi.v1.SetAIProviderSecretResponse

Field JSON key Type Cardinality Description
key_set keySet bool singular true when a non-empty key is now stored

Messages

AIProposal

AIProposal is a typed, schema-validated change proposal. Applying one calls an existing audited mutation RPC; this record never mutates live config itself.

Field JSON key Type Cardinality Description
id id string singular —
kind kind AIProposalKind singular —
patch_json patchJson string singular typed payload for the target mutation RPC
evidence_ids evidenceIds string repeated —
confidence confidence double singular —
model_id modelId string singular —
prompt_version promptVersion string singular —
status status AIProposalStatus singular —
applied_audit_id appliedAuditId string singular audit_event id once applied
created_at createdAt google.protobuf.Timestamp singular RFC 3339 string, e.g. 2026-07-26T09:00:00Z.
updated_at updatedAt google.protobuf.Timestamp singular RFC 3339 string, e.g. 2026-07-26T09:00:00Z.

ChatTurn

ChatTurn is one prior message in the conversation the client replays so the server stays stateless. Only operator (user) and assistant turns are sent; the system prompt and any tool/tool-result turns are reconstructed server-side and never accepted from the client (prompt-injection backstop).

Field JSON key Type Cardinality Description
role role string singular "user" | "assistant"
content content string singular —

LogEventRef

LogEventRef identifies one persisted log event to explain.

Field JSON key Type Cardinality Description
kind kind LogKind singular —
id id string singular —

LogTable

Field JSON key Type Cardinality Description
kind kind LogKind singular —
view view string singular operator's view, e.g. "simple" | "detail"
columns columns string repeated visible column headers, in display order
rows rows LogTableRow repeated current page rows, as displayed

LogTableRow

LogTable is the operator's CURRENT table view, sent verbatim: only the columns visible in the UI (simple vs detail), the rows on the current page, exactly as displayed. "What you see is what is analyzed" — no server-side sampling or aggregation. The handler caps row/cell counts and redacts secret substrings before the model sees it, but otherwise passes the cells through.

Field JSON key Type Cardinality Description
cells cells string repeated aligned 1:1 with LogTable.columns

SecurityEventQuery

SecurityEventQuery mirrors the typed, closed filter set of QuerySecurityEventsRequest (no free-form predicate, no SQL).

Field JSON key Type Cardinality Description
site_id siteId string singular —
client_ip_cidrs clientIpCidrs string repeated —
rule_ids ruleIds string repeated —
lookback_seconds lookbackSeconds int64 singular relative time window the NL implied JSON string (64-bit ints are quoted).
outcome outcome SecurityEventOutcome singular —

Enums

AIProposalKind

Value Number Description
AI_PROPOSAL_KIND_UNSPECIFIED 0 —
AI_PROPOSAL_KIND_CUSTOM_RULE 3 -> CustomRuleService (Phase 3)

AIProposalStatus

Value Number Description
AI_PROPOSAL_STATUS_UNSPECIFIED 0 —
AI_PROPOSAL_STATUS_DRAFT 1 —
AI_PROPOSAL_STATUS_ACCEPTED 2 —
AI_PROPOSAL_STATUS_REJECTED 3 —
AI_PROPOSAL_STATUS_SUPERSEDED 4 —

LogKind

LogKind selects which detail-log stream a log subject refers to.

Value Number Description
LOG_KIND_UNSPECIFIED 0 —
LOG_KIND_SECURITY 1 —
LOG_KIND_ACCESS 2 —
LOG_KIND_ERROR 3 —