ai

package
v1.8.2 Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2026 License: MIT Imports: 35 Imported by: 0

Documentation

Overview

Package ai implements kb's model probe, skill runner, and board tools over the local store.

Index

Constants

View Source
const (
	TruncatedReplyMessage   = "the model's reply hit the output limit and was cut off — ask for less in one request"
	ToolCallRequiredMessage = "model must support tool calling"
)
View Source
const (
	ProbeModelMissingMessage = "AI model not configured - fill in the model field"
	ProbeTimeoutMessage      = "the AI endpoint did not answer before the test timed out"
	ProbeCancelledMessage    = "the connection test was cancelled"
	ProbeDNSMessage          = "the AI base URL host does not resolve - check the base URL"
	ProbeTLSMessage          = "the AI endpoint's TLS handshake failed - check the scheme and the certificate"
	ProbeUnreachableMessage  = "could not connect to the AI endpoint - check the base URL and that the server is running"
	ProbeOpaqueMessage       = "upstream request failed"
)

Probe failure messages. A connection test that cannot say what failed is a test the operator cannot act on, so each of these names both the thing that went wrong and the field that fixes it. They are shown verbatim in the settings overlay, so they stay one short sentence with no secret in them.

View Source
const (
	UnknownSkillMessage        = unknownSkillMessage
	SkillsUnavailableMessage   = skillsUnavailableMessage
	SkillIterationLimitMessage = skillIterationLimitMessage
)
View Source
const CardLimitReachedMessage = cardLimitReachedMessage
View Source
const RunnerSystemPrompt = runnerSystemPrompt
View Source
const SkillMaxIterations = skillMaxIterations

Variables

View Source
var ErrPrivateAddress = errors.New("AI endpoint resolves to a private address (set KB_AI_ALLOW_PRIVATE=1 for local model servers)")

ErrPrivateAddress is the SSRF guard refusing a dial. It is a sentinel rather than an anonymous error because the message is the single most actionable thing the connection test can say - a local model server is the common case - and by the time the failure reaches the probe it has been through the dialer and transport, neither of which preserves error text.

Functions

func ClampPriority

func ClampPriority(p int) int

func NewHTTPClient

func NewHTTPClient() *http.Client

NewHTTPClient returns the guarded client used for model endpoints.

func NewLinkClient

func NewLinkClient() *http.Client

NewLinkClient returns the separately guarded client used by fetch_link.

func NormalizeStoryCount

func NormalizeStoryCount(max int) int

func ProposeCardTool

func ProposeCardTool(c *CardCollector) tool.Tool

func SkillBudget

func SkillBudget(maxTokens int64) int64

SkillBudget clamps a requested completion budget to the supported range.

func ValidateBaseURL

func ValidateBaseURL(base string) error

ValidateBaseURL applies the same endpoint validation used by model runs without constructing a client or reading a credential.

func ValidateDraft

func ValidateDraft(d Draft) error

Types

type CardCollector

type CardCollector = cardCollector

CardCollector owns the structured card output for one tool loop.

func NewCardCollector

func NewCardCollector(max int) *CardCollector

NewCardCollector creates a collector capped to one run's proposal budget.

type Config

type Config struct {
	BaseURL string
	Model   string
	Key     string
}

Config is one resolved OpenAI-compatible endpoint configuration.

type Draft

type Draft struct {
	Title  string       `json:"title"`
	Emoji  string       `json:"emoji"`
	Desc   string       `json:"desc"`
	Prio   int          `json:"prio"`
	Due    string       `json:"due"`
	Effort string       `json:"effort"`
	Tags   []string     `json:"tags"`
	Checks []DraftCheck `json:"checks"`
	Source int          `json:"-"`
}

Draft is one validated card proposal returned by a skill run.

func CoerceDraft

func CoerceDraft(m map[string]any) Draft

type DraftCheck

type DraftCheck struct {
	Text string `json:"text"`
	Done bool   `json:"done"`
}

type Error

type Error struct {
	Code    int
	Message string
	Cause   error
}

Error carries a caller-facing category. Code retains status-shaped values for compatibility; local callers use Error.As and Error.Unwrap.

func (*Error) Error

func (e *Error) Error() string

func (*Error) Unwrap

func (e *Error) Unwrap() error

type RunResult

type RunResult struct {
	Cards      []Draft `json:"cards"`
	Commentary string  `json:"commentary"`
	Partial    bool    `json:"-"`
}

RunResult is one completed run: the cards the model proposed through propose_card, and its closing prose. Partial marks a run that hit a budget with cards already collected — the cards are real, the set is not complete. It stays out of JSON, so a caller that drops the commentary must preserve the partial marker separately.

type Runner

type Runner struct {
	// contains filtered or unexported fields
}

Runner owns the direct store and clients used by AI runs.

func NewRunner

func NewRunner(st *store.Store, skillsDir string, aiClient, linkClient *http.Client) *Runner

NewRunner constructs a direct-store runner. Nil clients select the guarded defaults; explicit clients are a test and embedding seam.

func (*Runner) FetchLinkTool

func (r *Runner) FetchLinkTool() tool.Tool

func (*Runner) FindSimilarTool

func (r *Runner) FindSimilarTool(user string) tool.Tool

func (*Runner) GetTaskTool

func (r *Runner) GetTaskTool(user string) tool.Tool

func (*Runner) ListTasksTool

func (r *Runner) ListTasksTool(user string) tool.Tool

func (*Runner) LoadSkills

func (r *Runner) LoadSkills() ([]Skill, error)

LoadSkills returns the built-in skills with the operator's directory layered on top. An override replaces the built-in with the same frontmatter name. The operator directory is optional, but a malformed existing catalogue is a whole-catalogue failure.

func (*Runner) Probe

func (r *Runner) Probe(ctx context.Context, user string, supplied Config) error

Probe validates either the stored AI configuration or supplied form values. Blank supplied fields retain the stored value. A stored key never travels to a newly supplied origin.

func (*Runner) RunSkill

func (r *Runner) RunSkill(ctx context.Context, user string, scope Scope, skillName, input string, maxCards int, maxTokens int64) (RunResult, error)

runSkill executes one skill against the user's configured endpoint. The cards come from the collector the propose_card tool writes into, never from parsing the reply, so the model cannot smuggle a card past validateDraft and the count is capped by kb. maxTokens is the per-flow output budget: one card needs far less room than a whole ADR split, and the caller knows which flow it is.

func (*Runner) RunText

func (r *Runner) RunText(ctx context.Context, user, system, prompt string, maxTokens int64) (string, error)

RunText performs one tool-free completion using stored configuration without exposing the decrypted API key to callers.

func (*Runner) UpdateTaskTool

func (r *Runner) UpdateTaskTool(user string) tool.Tool

type Scope

type Scope int

Scope selects what one run may do. Imported or pasted documents use the read-only set because they can contain untrusted instructions. Full scope is reserved for input the local user explicitly authors for that authority.

const (
	ScopeReadOnly Scope = iota
	ScopeFull
)

type Skill

type Skill struct {
	Name        string
	Description string
	Body        string
}

Skill is one markdown instruction file with name and description frontmatter followed by the instruction body.

Jump to

Keyboard shortcuts

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