Documentation
¶
Overview ¶
Package selection defines the externalized selector interface that narrows a candidate set of skills or tools down to the items most relevant for the current turn.
PromptKit owns pack semantics (eligibility, query derivation, when to select, fallback on error). A Selector owns the ranking algorithm: it may use embeddings, a rerank service, BM25, an LLM judge, or plain rules. PromptKit hands it a query and candidates and receives IDs. No vectors or scores cross the interface boundary.
Index ¶
Constants ¶
const DefaultRerankTimeout = 5 * time.Second
DefaultRerankTimeout bounds one selection round's rerank calls.
Selection sits on the turn's critical path — the skill path runs once per Send, the tool path once per provider round — so an unbounded call lets a stalled reranker hold the whole turn open. The fallback when it expires is cheap by construction: Select returns an error and PromptKit includes all eligible candidates, which is what would have happened without a selector.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Candidate ¶
Candidate describes one item a Selector may choose to surface. IDs are stable identifiers (skill name, tool name); the rest is descriptive context for the ranker.
type ExecClient ¶
type ExecClient struct {
// contains filtered or unexported fields
}
ExecClient is a Selector that delegates ranking to an external process. Spawning goes through a Sandbox so the process can run on-host, in a sidecar, or wherever the sandbox dictates.
func NewExecClient ¶
func NewExecClient(cfg ExecClientConfig) *ExecClient
NewExecClient constructs an ExecClient from the given config. Sandbox defaults to the built-in direct backend when nil.
func (*ExecClient) Init ¶
func (c *ExecClient) Init(SelectorContext) error
Init is a no-op for ExecClient. The subprocess owns whatever resources it needs; PromptKit holds no state on its behalf.
func (*ExecClient) Name ¶
func (c *ExecClient) Name() string
Name returns the configured selector name.
func (*ExecClient) Select ¶
Select serializes the request, spawns the subprocess via the sandbox, and parses selected IDs from stdout. On any failure (process error, timeout, invalid JSON) it returns the error unchanged; callers are expected to treat a non-nil error as "include all eligible" rather than crashing the conversation.
type ExecClientConfig ¶
type ExecClientConfig struct {
Name string
Command string
Args []string
Env []string
TimeoutMs int
Sandbox sandbox.Sandbox
}
ExecClientConfig configures an exec-backed Selector. The subprocess reads a single JSON object on stdin and writes a JSON object on stdout (see wire protocol below). When Sandbox is nil, the built-in direct backend is used.
type Query ¶
type Query struct {
Text string
Kind string // "skill" | "tool"
PackID string
AgentID string
K int // desired max results; selector may return fewer
}
Query carries the context PromptKit has assembled for this selection round. Kind distinguishes skills from tools so one Selector implementation can serve both hook points.
type RerankSelector ¶ added in v2.6.0
type RerankSelector struct {
// contains filtered or unexported fields
}
RerankSelector narrows a candidate set with a rerank provider: it ranks each candidate's description against the turn's query and returns the best IDs in order.
A note on where to use it. The skill path selects once per Send and is the safer first target. The tool path selects once per provider round, and changing the tool set between rounds invalidates the provider's cached prompt prefix — a per-round rerank can cost more tokens than the narrowing saves, so measure before turning it on there.
Scores never leave this type. PromptKit's selector boundary takes IDs only, and rerank scores are not comparable across providers or models anyway.
func NewRerankSelector ¶ added in v2.6.0
func NewRerankSelector(opts ...RerankSelectorOption) *RerankSelector
NewRerankSelector creates a selector that ranks with the rerank provider handed to Init.
func (*RerankSelector) Init ¶ added in v2.6.0
func (s *RerankSelector) Init(ctx SelectorContext) error
Init takes the rerank provider from the context, and fails without one.
Failing is the point: Select's fallback is "include all eligible", so a selector that degraded silently would be indistinguishable from one that ran and chose everything.
func (*RerankSelector) Name ¶ added in v2.6.0
func (s *RerankSelector) Name() string
Name identifies the selector for registration and config.
func (*RerankSelector) Select ¶ added in v2.6.0
func (s *RerankSelector) Select( ctx context.Context, q Query, candidates []Candidate, ) ([]string, error)
Select orders candidates by relevance to q.Text and returns their IDs, best first, at most q.K of them.
An error here means PromptKit falls back to including every eligible candidate. That is the caller's policy, not this selector's, so a provider failure is reported rather than swallowed.
type RerankSelectorOption ¶ added in v2.6.0
type RerankSelectorOption func(*RerankSelector)
RerankSelectorOption configures a RerankSelector.
func WithRerankTimeout ¶ added in v2.6.0
func WithRerankTimeout(d time.Duration) RerankSelectorOption
WithRerankTimeout overrides DefaultRerankTimeout. A non-positive value leaves the default in place rather than disabling the bound.
type Selector ¶
type Selector interface {
Name() string
Init(ctx SelectorContext) error
Select(ctx context.Context, q Query, candidates []Candidate) ([]string, error)
}
Selector narrows a candidate set. Returning an error or an empty result tells PromptKit to fall back to "include all eligible"; Selectors must never panic. Implementations should be safe for concurrent use.
type SelectorContext ¶
type SelectorContext struct {
Embeddings providers.EmbeddingProvider
// Rerank is the configured rerank provider, for selectors that rank
// by relevance to the turn's query rather than by vector distance.
// Nil when the host configured none.
Rerank providers.RerankProvider
}
SelectorContext is handed to Init. It carries shared infrastructure selectors may opt into — most notably the configured embedding provider, so in-process selectors can reuse the same instance RAG uses instead of constructing their own. Any field may be nil.
A selector that needs a field it did not get must fail Init rather than degrade silently: Select's fallback is "include all eligible", which is indistinguishable from a selector that ran and chose everything.