toolsig

package
v0.51.0 Latest Latest
Warning

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

Go to latest
Published: Jul 16, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package toolsig compiles deterministic compact tool signatures (Spec 085, Compact Router) from a tool's JSON Schema (ToolMetadata.ParamsJSON) and its description.

The normative grammar — type abbreviations, the required (*) and lossy (~) markers, atom quoting, parameter ordering, the (~) unparseable-schema fallback, and the first-sentence terminator rules — lives in specs/085-compact-router/contracts/signature-grammar.md. Worked examples E1–E11 in that contract are pinned byte-for-byte by this package's tests.

IMPORT RULE: this is a LEAF package. It MUST NOT import internal/server (or anything that pulls the HTTP/MCP server surface): the spec-083 bench arms (bench/arms) must be able to import the same grammar (FR-019) without dragging in the server, and internal/server itself imports this package. Allowed dependencies: stdlib only.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FirstSentence

func FirstSentence(description string) string

FirstSentence extracts the deterministic verbatim first-sentence prefix of a description (grammar contract §6): the earliest matching terminator of either class wins; with no terminator in the first maxDescPrefix runes the verbatim capped prefix is returned (rune-boundary safe), with a trailing "…" only when truncation actually occurred. Empty/whitespace-only input yields "".

Types

type Cache

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

Cache memoizes compiled Signatures keyed by the indexed per-tool hash (ToolMetadata.Hash — the Spec-032 SHA-256 covering description + schemas, so definition changes and index rebuilds naturally invalidate entries by changing the key). Process-local, never persisted; re-warms on restart via the normal reindex (FR-008).

Exactly ONE instance must exist per process: Runtime owns it, the indexing path warms it, and the MCP request path reads it — see the wiring test in internal/server. A read-mostly RWMutex is used instead of a channel-owned actor per the plan's Complexity Tracking (pure memoized derivation of an immutable input).

func NewCache

func NewCache() *Cache

NewCache creates an empty signature cache.

func (*Cache) CompileCount

func (c *Cache) CompileCount() int64

CompileCount reports how many signatures were compiled-and-stored (one per unique hash). Test/observability hook — FR-008's falsifier.

func (*Cache) Get

func (c *Cache) Get(hash, paramsJSON, description string) Signature

Get returns the Signature for hash, compiling (and memoizing) it from paramsJSON/description on a miss. Concurrent callers may compile redundantly under contention, but exactly one result is stored and counted.

func (*Cache) Len

func (c *Cache) Len() int

Len reports the number of cached signatures (bounded by live tool count).

func (*Cache) RetainHashes

func (c *Cache) RetainHashes(live map[string]struct{}) int

RetainHashes reconciles the cache to the live tool set: every entry whose hash is NOT in live is evicted, and the number of evictions is returned. The indexing path calls this after index rebuilds/differential updates so stale hashes (removed or redefined tools) do not accumulate for the life of the process — Warm only ever adds. A nil/empty live set clears the cache. Safe for concurrent use with Get/Warm: eviction holds the write lock, and a racing Get for an evicted hash simply recompiles (rendering is pure).

func (*Cache) Warm

func (c *Cache) Warm(hash, paramsJSON, description string)

Warm pre-compiles the Signature for hash so later Gets are pure cache hits. Called from the indexing path (FR-008 "compiled at index time") — the authoritative source of fresh hashes, so unlike Get it always memoizes and admits the hash to the live set (indexing may warm a new hash before the post-update reconcile runs; without this, that warm would be dropped by the Get-side stale gate).

type Signature

type Signature struct {
	Sig   string // e.g. "(origin*:str, ttl:int=3600, account~:obj)"; "()" for no params; "(~)" for an unparseable schema
	Desc  string // first-sentence verbatim prefix (may be "")
	Lossy bool   // true iff any param (or the whole schema) collapsed under "~" (FR-004)
}

Signature is the deterministic compact rendering of one tool (Spec 085, data-model §1). Sig is the parenthesized parameter list; Desc is the verbatim first-sentence prefix of the description; Lossy is true iff Sig contains at least one "~" (strict biconditional — grammar contract §1).

func Render

func Render(paramsJSON, description string) (Signature, error)

Render compiles a tool's stored input schema (ParamsJSON) and description into its compact Signature per the normative grammar (specs/085-compact-router/contracts/signature-grammar.md).

Rendering is fail-soft: it NEVER returns an unusable Signature. When paramsJSON cannot be parsed as an object schema, the returned Signature is the "(~)" fallback (Lossy=true, E11) and the error describes why — callers may log the error but must still use the Signature; failing the whole response on it would violate the contract.

Jump to

Keyboard shortcuts

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