llm

package
v0.9.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 12, 2026 License: MIT Imports: 3 Imported by: 0

Documentation

Overview

Package llm holds shared primitives for LLM-driven permission decisions.

FallthroughKind* values are stored verbatim in metrics entries. Only FallthroughKindLLM is promotable via fallthrough_strategy (allow|deny). The other kinds indicate runtime-mode or configuration conditions and must always defer to the upstream tool's prompt.

FallthroughKindAPIUnusable means the API truncated/refused the response or returned no parseable text. It is intentionally NOT subject to fallthrough_strategy because the LLM never actually expressed an uncertain decision — auto-allowing on a refused/truncated response would silently weaken security.

FallthroughKindCredentialUnavailable covers credential-resolution failure on the auth.type=exec / auth.type=file path (the helper / file itself, the cache layer behind them, and provider 401/403 responses that suggest a stale or invalid key). It is distinct from FallthroughKindNoAPIKey, which is reserved for "the user never set any key at all". Like the other runtime-mode kinds, it is not affected by fallthrough_strategy: helper failure is not LLM uncertainty.

Index

Constants

View Source
const (
	FallthroughKindUserInteraction       = "user_interaction"
	FallthroughKindBypass                = "bypass"
	FallthroughKindDontAsk               = "dontask"
	FallthroughKindUnknownProvider       = "unknown_provider"
	FallthroughKindNoAPIKey              = "no_apikey"
	FallthroughKindCredentialUnavailable = "credential_unavailable" //nolint:gosec // metrics classifier value, not a credential
	FallthroughKindLLM                   = "llm"
	FallthroughKindAPIUnusable           = "api_unusable"
)
View Source
const (
	FallthroughStrategyAsk   = "ask"
	FallthroughStrategyAllow = "allow"
	FallthroughStrategyDeny  = "deny"
)

FallthroughStrategy values control what ccgate does when the LLM returns "fallthrough" (or an empty/unexpected behavior). Only the LLM kind is affected — runtime-mode fallthroughs (bypass, dontAsk, no_apikey, etc.) always defer to the upstream tool's prompt regardless of this setting.

View Source
const (
	BehaviorAllow       = "allow"
	BehaviorDeny        = "deny"
	BehaviorFallthrough = "fallthrough"
)

Behavior values returned by the LLM (and emitted by Decide).

View Source
const DefaultDenyMessage = "Automatically denied as potentially dangerous."

DefaultDenyMessage is used when the LLM signals deny but emits no concrete deny_message. Targets may override per request before rendering the final response.

Variables

This section is empty.

Functions

This section is empty.

Types

type Decision

type Decision struct {
	Behavior string `json:"behavior"`
	Message  string `json:"message,omitempty"`
}

Decision is the final allow/deny resolved from an LLM Output (after fallthrough_strategy is applied) and rendered into a target-specific response shape by the caller.

func ApplyStrategy

func ApplyStrategy(strategy, llmReason string) (Decision, bool)

ApplyStrategy converts an LLM-uncertainty fallthrough into a forced allow/deny based on `strategy`. Returns ok=false when the strategy is "ask" (or unrecognized), preserving the original fallthrough behavior.

On the message field: target hooks (Claude Code, Codex CLI) only deliver decision.message to the AI when behavior is "deny"; the allow-side message is silently ignored. We still populate it so that (a) it shows up in our own logs / metrics for auditing and (b) it works as a forward-compatible hint if upstreams ever start delivering allow-side messages.

type Output

type Output struct {
	Behavior    string `json:"behavior"     jsonschema_description:"One of allow, deny, fallthrough."`
	Reason      string `json:"reason"       jsonschema_description:"Brief reason for the decision. Always provide this regardless of behavior."`
	DenyMessage string `` /* 129-byte string literal not displayed */
}

Output is the structured response from the LLM.

type Prompt

type Prompt struct {
	System    string
	User      string
	Model     string
	TimeoutMS int
}

Prompt is what targets feed into Provider.Decide.

type Provider

type Provider interface {
	Decide(ctx context.Context, p Prompt) (Result, error)
}

Provider abstracts a single LLM call. Implementations live under internal/llm/<provider>/ (e.g. anthropic). Tests use a fake provider to avoid real network calls.

type Result

type Result struct {
	Output   Output
	Usage    *Usage
	Unusable bool
}

Result wraps Output + Usage with an Unusable flag set when the API truncated/refused the response or returned no parseable text. Targets must not treat Unusable=true as a real LLM "fallthrough" — the LLM never actually expressed uncertainty, so fallthrough_strategy must not promote it to allow/deny.

type Usage

type Usage struct {
	InputTokens  int64
	OutputTokens int64
}

Usage holds token usage from a single LLM call.

Directories

Path Synopsis
Package anthropic implements llm.Provider against the Anthropic Messages API.
Package anthropic implements llm.Provider against the Anthropic Messages API.
Package gemini implements llm.Provider against the Google Gemini API via its OpenAI-compatible endpoint.
Package gemini implements llm.Provider against the Google Gemini API via its OpenAI-compatible endpoint.
Package openai implements llm.Provider against the OpenAI Chat Completions API.
Package openai implements llm.Provider against the OpenAI Chat Completions API.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL