Documentation
¶
Overview ¶
Package knowledgepage is the store and ranked-search backend for canonical business/domain knowledge pages (#633): org-shared markdown documents stored inline in Postgres so their content is vector- and full-text searchable. It is a sibling of the portal package (not part of it) so the portal package stays within its size budget; the portal REST handler and the unified-search provider consume this package's Store and Searcher.
Index ¶
- Constants
- Variables
- func AssetRef(id string) string
- func ConnectionRef(kind, name string) string
- func IndexText(title, body string, tags []string) string
- func NewID() string
- func NewRefID() string
- func NewVersionID() string
- func PageReference(id string) string
- func PromptRef(id string) string
- type EntityRef
- type Filter
- type Page
- type PageRef
- type ReverseLookup
- type ScoredPage
- type SearchQuery
- type Searcher
- type Store
- type Update
- type Version
Constants ¶
const ( RefTargetAsset = "asset" RefTargetPrompt = "prompt" RefTargetCollection = "collection" RefTargetKnowledgePage = "knowledge_page" RefTargetConnection = "connection" RefTargetDataHub = "datahub" )
Entity-reference target types. Exactly one target is set on a reference row: an internal entity by foreign key, or an external DataHub URN.
const ( RefSourcePromoted = "promoted" // carried from a source insight by apply_knowledge RefSourceManual = "manual" // added explicitly through the authoring picker RefSourceInline = "inline" // derived from a mention in the page body )
Entity-reference sources, recording how a reference came to be so the inline body-scan (a later phase) can reconcile only its own rows without clobbering picked or promoted references.
const (
DefaultSearchLimit = 20
)
Search result limits, mirroring pkg/portal so every ranked surface clamps the same way. DefaultSearchLimit is the top-K when the caller does not specify one; maxSearchLimit bounds an explicit request.
Variables ¶
var ErrNotFound = errors.New("knowledge page not found")
ErrNotFound is returned when a page id/slug does not resolve to a live page.
var ErrRefTargetNotFound = errors.New("entity reference target does not exist")
ErrRefTargetNotFound is returned when a reference points at an internal entity (asset, prompt, collection, page, connection) that does not exist, so the foreign key rejects it. Callers map it to a client error rather than a 500.
Functions ¶
func AssetRef ¶ added in v1.90.0
AssetRef returns the canonical reference for an asset, or "" if id is empty.
func ConnectionRef ¶ added in v1.90.0
ConnectionRef returns the canonical reference for a connection, or "" if kind or name is empty.
func IndexText ¶
IndexText composes the text a page is embedded and lexically indexed on: its title, body, and tags. The indexjobs knowledge-pages consumer and the request-path search MUST agree on this composition so a stored embedding lives in the same space as the query; portal_knowledge_page_fts (migration 000070) composes the same corpus from the same columns. Empty fields are skipped so a sparse page does not pad the text.
func NewRefID ¶
func NewRefID() string
NewRefID returns a unique id for an entity-reference row ("kpr_<uuid>").
func NewVersionID ¶
func NewVersionID() string
NewVersionID returns a unique id for a page version ("kpv_<uuid>").
func PageReference ¶ added in v1.90.0
PageReference returns the canonical reference for a knowledge page, or "" if id is empty. It is not named PageRef to avoid colliding with the PageRef type.
Types ¶
type EntityRef ¶
type EntityRef struct {
ID string `json:"id,omitempty"`
PageID string `json:"page_id,omitempty"`
TargetType string `json:"target_type"`
AssetID string `json:"asset_id,omitempty"`
PromptID string `json:"prompt_id,omitempty"`
CollectionID string `json:"collection_id,omitempty"`
RefPageID string `json:"ref_page_id,omitempty"`
ConnectionKind string `json:"connection_kind,omitempty"`
ConnectionName string `json:"connection_name,omitempty"`
EntityURN string `json:"entity_urn,omitempty"`
Source string `json:"source,omitempty"`
CreatedBy string `json:"created_by,omitempty"`
CreatedAt time.Time `json:"created_at"`
}
EntityRef is a typed reference from a knowledge page to an entity it provides knowledge about. Exactly one target is populated, matching TargetType.
func DataHubRef ¶
DataHubRef builds a reference to an external DataHub entity (a urn:li: URN). This is the only reference type Phase 0 writes: the references apply_knowledge carries from a promoted insight.
func ParseEntityRef ¶
ParseEntityRef parses a serialized reference (the inverse of URN) into a typed EntityRef. A "urn:" reference is an external (DataHub) URN, stored verbatim; an "mcp:" reference resolves to the matching internal target. Source and the owning page id are not part of the serialized form and are left to the caller.
func ScanBodyRefs ¶
ScanBodyRefs extracts the entity references mentioned in a page's markdown body. It is content-agnostic: a reference is found whether it appears as a markdown link href, an autolink, or inline text. Unparseable matches are skipped, the result is de-duplicated by target, and every ref is marked source=inline so a reconcile can replace only the inline set without touching promoted or manual references.
type Filter ¶
Filter narrows a knowledge page listing. Tag filters to pages carrying the tag; Query is a substring match on title for the browse UI. Only non-deleted pages are ever returned.
type Page ¶
type Page struct {
ID string `json:"id" example:"kp_01HK7R8Z8M0Y6A5G1R6FQ2VQNK"`
Slug string `json:"slug,omitempty" example:"fiscal-calendar"`
Title string `json:"title" example:"Fiscal Calendar"`
Summary string `json:"summary,omitempty" example:"How the company defines fiscal quarters."`
Body string `json:"body" example:"# Fiscal Calendar\n\nQ1 begins..."`
Tags []string `json:"tags"`
CreatedBy string `json:"created_by,omitempty" example:"alice@example.com"`
CreatedEmail string `json:"created_email,omitempty" example:"alice@example.com"`
UpdatedBy string `json:"updated_by,omitempty" example:"bob@example.com"`
CurrentVersion int `json:"current_version" example:"3"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
DeletedAt *time.Time `json:"deleted_at,omitempty"`
}
Page is a canonical unit of business/domain knowledge: a markdown page in the platform's internal knowledge store (the sibling of DataHub). It is org-shared, not owner-scoped: every caller can read it, and personas with apply_knowledge access edit it. The markdown body is stored inline (not in S3) so page CONTENT is directly embeddable and full-text searchable.
type PageRef ¶
PageRef identifies a knowledge page that references an entity. It is the result of the reverse lookup (the pages that reference a target), the counterpart of ListEntityRefs (a page's references).
func PagesForURNs ¶ added in v1.89.0
func PagesForURNs(ctx context.Context, store ReverseLookup, urns []string, limit int) ([]PageRef, error)
PagesForURNs returns the distinct pages that reference any of the given entity URNs, in first-seen order, capped at limit (limit <= 0 means no cap). A URN that does not parse as a reference is skipped; a lookup error is returned. It backs the cross-enrichment that surfaces the knowledge about the entities a tool returns.
type ReverseLookup ¶ added in v1.89.0
type ReverseLookup interface {
ListPagesReferencing(ctx context.Context, ref EntityRef) ([]PageRef, error)
}
ReverseLookup is the reverse-lookup capability PagesForURNs needs (the pages that reference a target), satisfied by Store and by lighter adapters in callers.
type ScoredPage ¶
ScoredPage pairs a page with its relevance score in [0,1].
type SearchQuery ¶
type SearchQuery struct {
Embedding []float32 // query vector; nil selects lexical-only ranking
QueryText string // raw query text for the lexical arm
Limit int // max results; clamped into [1, maxSearchLimit]
}
SearchQuery describes a relevance ranking request over canonical knowledge pages. Unlike asset search, there is NO owner scope: knowledge pages are org-shared, so every non-deleted page is rankable for every caller. A nil Embedding selects lexical-only ranking (graceful degradation when no embedding provider is configured); a non-nil Embedding selects hybrid ranking.
func (SearchQuery) EffectiveLimit ¶
func (q SearchQuery) EffectiveLimit() int
EffectiveLimit clamps the requested limit into the search bounds.
type Searcher ¶
type Searcher interface {
Search(ctx context.Context, q SearchQuery) ([]ScoredPage, error)
}
Searcher ranks knowledge pages by relevance to a query. It is a capability separate from Store so the feature degrades to absent (rather than forcing every store to carry a ranking query) on a deployment without pgvector.
type Store ¶
type Store interface {
Insert(ctx context.Context, page Page) error
Get(ctx context.Context, id string) (*Page, error)
GetBySlug(ctx context.Context, slug string) (*Page, error)
List(ctx context.Context, filter Filter) ([]Page, int, error)
Update(ctx context.Context, id string, updates Update) error
SoftDelete(ctx context.Context, id string) error
ListVersions(ctx context.Context, pageID string, limit, offset int) ([]Version, int, error)
GetVersion(ctx context.Context, pageID string, version int) (*Version, error)
// Entity references (#664): the entities a page provides knowledge about.
ListEntityRefs(ctx context.Context, pageID string) ([]EntityRef, error)
// ValidateRefTargets checks each FK-backed reference target exists, so a
// citation to a missing entity is rejected before the page is written (#690).
ValidateRefTargets(ctx context.Context, refs []EntityRef) error
// FilterExistingRefTargets returns the subset of refs whose target exists,
// dropping stale references carried from a source insight (#690).
FilterExistingRefTargets(ctx context.Context, refs []EntityRef) ([]EntityRef, error)
AddEntityRefs(ctx context.Context, pageID string, refs []EntityRef) error
ReplaceEntityRefs(ctx context.Context, pageID string, refs []EntityRef) error
ReplaceEntityRefsBySource(ctx context.Context, pageID, source string, refs []EntityRef) error
// ListPagesReferencing is the reverse lookup: the pages that reference a target.
ListPagesReferencing(ctx context.Context, ref EntityRef) ([]PageRef, error)
}
Store persists and queries canonical knowledge pages.
func NewPostgresStore ¶
NewPostgresStore creates a PostgreSQL knowledge page store.
type Update ¶
type Update struct {
Slug *string
Title *string
Summary *string
Body *string
Tags *[]string
UpdatedBy string
ChangeSummary string
}
Update carries the editable fields of a page. A nil pointer means "leave unchanged"; a non-nil pointer (including empty string) sets the field. Whenever Title, Body, or Tags change, the store clears the embedding columns so the indexjobs reconciler re-embeds the new content off the request path.
type Version ¶
type Version struct {
ID string `json:"id" example:"kpv_01HK7R9A"`
PageID string `json:"page_id" example:"kp_01HK7R8Z8M0Y6A5G1R6FQ2VQNK"`
Version int `json:"version" example:"2"`
Title string `json:"title" example:"Fiscal Calendar"`
Summary string `json:"summary,omitempty"`
Body string `json:"body"`
Tags []string `json:"tags"`
CreatedBy string `json:"created_by,omitempty" example:"bob@example.com"`
ChangeSummary string `json:"change_summary,omitempty" example:"Clarified Q1 start"`
CreatedAt time.Time `json:"created_at"`
}
Version records a single saved version of a page's content. The body is stored inline (pages are text-first and bounded), unlike asset versions which reference S3 keys.