222 lines
8.9 KiB
Go
222 lines
8.9 KiB
Go
package promptkit
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
internalengine "gitea.maximumdirect.net/eric/promptkit/internal/engine"
|
|
)
|
|
|
|
// NamespaceFilterMode selects namespace membership for an identity listing.
|
|
type NamespaceFilterMode uint8
|
|
|
|
const (
|
|
// NamespaceDefault uses the engine view's scope, or all IDs if it is unset.
|
|
NamespaceDefault NamespaceFilterMode = iota
|
|
// NamespaceNamed selects IDs whose exact namespace matches Name.
|
|
NamespaceNamed
|
|
// NamespaceUnqualified selects IDs without a namespace.
|
|
NamespaceUnqualified
|
|
// NamespaceAll selects IDs from every namespace, overriding the view scope.
|
|
NamespaceAll
|
|
)
|
|
|
|
// NamespaceFilter optionally overrides the namespace used for one listing.
|
|
// NamespaceNamed requires a nonempty valid namespace in Name; other modes
|
|
// ignore Name.
|
|
type NamespaceFilter struct {
|
|
Mode NamespaceFilterMode
|
|
Name string
|
|
}
|
|
|
|
// ResourceKind selects one identity type for [Engine.ListNamespaces].
|
|
type ResourceKind string
|
|
|
|
const (
|
|
// ResourcePrompt selects namespaces containing prompt IDs.
|
|
ResourcePrompt ResourceKind = "prompt"
|
|
// ResourceProfile selects namespaces containing profile IDs.
|
|
ResourceProfile ResourceKind = "profile"
|
|
// ResourceBackend selects namespaces containing backend IDs.
|
|
ResourceBackend ResourceKind = "backend"
|
|
)
|
|
|
|
// CollectionInfo describes one effective collections declaration.
|
|
type CollectionInfo struct {
|
|
// Namespace is the exact collection key.
|
|
Namespace string
|
|
// ReleaseVersion is nil when absent or null and points to the exact value
|
|
// when present, including an explicitly empty string.
|
|
ReleaseVersion *string
|
|
}
|
|
|
|
// PromptIdentity identifies one prompt ID and its optional descriptive version
|
|
// label in the effective configuration captured when an Engine is constructed.
|
|
// A nil Version means no label was declared; a non-nil empty string is an
|
|
// explicit label. It has no stable JSON representation.
|
|
type PromptIdentity struct {
|
|
ID string
|
|
Version *string
|
|
}
|
|
|
|
// ListProfiles returns profile IDs in the effective configuration captured
|
|
// when the engine was constructed. Maintained and consumer profiles are
|
|
// included; an inherited profile retains its own ID. IDs are preserved exactly
|
|
// and sorted lexically. An omitted filter or NamespaceDefault uses the view's
|
|
// profile namespace, or all profiles when unset. NamespaceNamed selects the
|
|
// exact named namespace, NamespaceUnqualified selects IDs without a slash, and
|
|
// NamespaceAll selects every profile. An explicit filter replaces the view's
|
|
// default for this call. At most one filter is accepted.
|
|
//
|
|
// The returned slice is caller-owned and safe to mutate while the engine is
|
|
// used concurrently. Empty inventories succeed.
|
|
//
|
|
// Listing reports membership, not execution readiness. It does not reload
|
|
// configuration or perform resource, credential, provider, or execution work.
|
|
// Profile IDs are application data and may be sensitive. A nil or zero-value
|
|
// engine returns an error matching ErrInvalidConfig. Cancellation or deadline
|
|
// expiration returns the context error and no partial result. Multiple
|
|
// filters, an unknown mode, or an invalid named namespace returns an error
|
|
// matching ErrInvalidRequest.
|
|
func (e *Engine) ListProfiles(ctx context.Context, filters ...NamespaceFilter) ([]string, error) {
|
|
if e == nil || e.internal == nil {
|
|
return nil, fmt.Errorf("%w: engine is nil", ErrInvalidConfig)
|
|
}
|
|
|
|
profiles, err := e.internal.ListProfiles(ctx, internalListingFilters(filters)...)
|
|
if err != nil {
|
|
return nil, mapPublicError(err)
|
|
}
|
|
return profiles, nil
|
|
}
|
|
|
|
// ListPrompts returns prompt IDs in the effective configuration captured when
|
|
// the engine was constructed, sorted lexically by ID. Each identity may include
|
|
// its descriptive version label. Its optional filter follows the same
|
|
// NamespaceDefault, NamespaceNamed, NamespaceUnqualified, and NamespaceAll
|
|
// behavior as [Engine.ListProfiles], using the prompt namespace by default.
|
|
// At most one filter is accepted.
|
|
//
|
|
// The returned slice and each Version pointer are caller-owned and safe to
|
|
// mutate while the engine is used concurrently. Empty inventories succeed.
|
|
//
|
|
// Listing reports membership, not execution readiness. It does not reload
|
|
// configuration or perform resource, credential, provider, or execution work.
|
|
// Prompt identities are application data and may be sensitive. A nil or
|
|
// zero-value engine returns an error matching ErrInvalidConfig. Cancellation
|
|
// or deadline expiration returns the context error and no partial result.
|
|
// Multiple filters, an unknown mode, or an invalid named namespace returns an
|
|
// error matching ErrInvalidRequest.
|
|
func (e *Engine) ListPrompts(ctx context.Context, filters ...NamespaceFilter) ([]PromptIdentity, error) {
|
|
if e == nil || e.internal == nil {
|
|
return nil, fmt.Errorf("%w: engine is nil", ErrInvalidConfig)
|
|
}
|
|
|
|
identities, err := e.internal.ListPrompts(ctx, internalListingFilters(filters)...)
|
|
if err != nil {
|
|
return nil, mapPublicError(err)
|
|
}
|
|
public := make([]PromptIdentity, len(identities))
|
|
for i, identity := range identities {
|
|
public[i] = PromptIdentity{ID: identity.ID, Version: copyStringPtr(identity.Version)}
|
|
}
|
|
if err := ctx.Err(); err != nil {
|
|
return nil, mapPublicError(err)
|
|
}
|
|
return public, nil
|
|
}
|
|
|
|
// ListBackends returns backend IDs in the effective configuration captured
|
|
// when the engine was constructed, sorted lexically by full ID. Its optional
|
|
// filter follows the same namespace behavior as [Engine.ListProfiles], using
|
|
// the backend namespace by default. At most one filter is accepted. The
|
|
// returned slice is caller-owned and safe to mutate while the engine is used
|
|
// concurrently. Empty inventories succeed.
|
|
//
|
|
// Listing reports membership, not execution readiness, and performs no
|
|
// provider or execution work. A nil or zero-value engine returns an error
|
|
// matching ErrInvalidConfig. Cancellation or deadline expiration returns the
|
|
// context error and no partial result. Multiple filters, an unknown mode, or
|
|
// an invalid named namespace returns an error matching ErrInvalidRequest.
|
|
func (e *Engine) ListBackends(ctx context.Context, filters ...NamespaceFilter) ([]string, error) {
|
|
if e == nil || e.internal == nil {
|
|
return nil, fmt.Errorf("%w: engine is nil", ErrInvalidConfig)
|
|
}
|
|
backends, err := e.internal.ListBackends(ctx, internalListingFilters(filters)...)
|
|
if err != nil {
|
|
return nil, mapPublicError(err)
|
|
}
|
|
return backends, nil
|
|
}
|
|
|
|
func internalListingFilters(filters []NamespaceFilter) []internalengine.ListingFilter {
|
|
if filters == nil {
|
|
return nil
|
|
}
|
|
internal := make([]internalengine.ListingFilter, len(filters))
|
|
for index, filter := range filters {
|
|
internal[index] = internalengine.ListingFilter{
|
|
Mode: internalengine.ListingFilterMode(filter.Mode),
|
|
Name: filter.Name,
|
|
}
|
|
}
|
|
return internal
|
|
}
|
|
|
|
// ListNamespaces returns the sorted, distinct namespaces that contain the
|
|
// selected resource kinds. With no kinds, it returns the union across prompts,
|
|
// profiles, and backends. Repeated kinds have no effect; an unknown kind
|
|
// returns an error matching ErrInvalidRequest. The inventory is global and is
|
|
// not restricted by this engine view's scopes. Unqualified resource IDs do
|
|
// not contribute a namespace.
|
|
//
|
|
// The returned slice is caller-owned. A nil or zero-value engine returns an
|
|
// error matching ErrInvalidConfig. Cancellation or deadline expiration
|
|
// returns the context error and no partial result.
|
|
func (e *Engine) ListNamespaces(ctx context.Context, kinds ...ResourceKind) ([]string, error) {
|
|
if e == nil || e.internal == nil {
|
|
return nil, fmt.Errorf("%w: engine is nil", ErrInvalidConfig)
|
|
}
|
|
internalKinds := make([]string, len(kinds))
|
|
for index, kind := range kinds {
|
|
internalKinds[index] = string(kind)
|
|
}
|
|
namespaces, err := e.internal.ListNamespaces(ctx, internalKinds)
|
|
if err != nil {
|
|
return nil, mapPublicError(err)
|
|
}
|
|
return namespaces, nil
|
|
}
|
|
|
|
// ListCollections returns the sorted collection declarations from the
|
|
// effective configuration captured when the engine was constructed. It
|
|
// includes metadata-only and resource-only declarations and is independent of
|
|
// namespace view scopes. It does not infer collections from resource IDs or
|
|
// configuration source history.
|
|
//
|
|
// The returned slice and each ReleaseVersion pointer are caller-owned. Nil
|
|
// means the label was absent or null; a non-nil empty string is preserved. A
|
|
// nil or zero-value engine returns an error matching ErrInvalidConfig.
|
|
// Cancellation or deadline expiration returns the context error and no partial
|
|
// result.
|
|
func (e *Engine) ListCollections(ctx context.Context) ([]CollectionInfo, error) {
|
|
if e == nil || e.internal == nil {
|
|
return nil, fmt.Errorf("%w: engine is nil", ErrInvalidConfig)
|
|
}
|
|
collections, err := e.internal.ListCollections(ctx)
|
|
if err != nil {
|
|
return nil, mapPublicError(err)
|
|
}
|
|
public := make([]CollectionInfo, len(collections))
|
|
for index, collection := range collections {
|
|
public[index] = CollectionInfo{
|
|
Namespace: collection.Namespace,
|
|
ReleaseVersion: copyStringPtr(collection.ReleaseVersion),
|
|
}
|
|
}
|
|
if err := ctx.Err(); err != nil {
|
|
return nil, mapPublicError(err)
|
|
}
|
|
return public, nil
|
|
}
|