diff --git a/backends.go b/backends.go index fd6e79d..33774fd 100644 --- a/backends.go +++ b/backends.go @@ -44,13 +44,13 @@ type BackendSmokeTestConfig struct { // DefaultProfile is the exact profile ID selected as the backend's // diagnostic inference default. A supplied value must not be blank; the ID // is resolved only when that default is selected. - DefaultProfile *string + DefaultProfile *string `json:"default_profile,omitempty" yaml:"default_profile,omitempty"` // Reachability optionally selects a full HTTP destination for reachability // diagnostics. A nil endpoint uses the effective backend endpoint. - Reachability *ReachabilityProbeConfig + Reachability *ReachabilityProbeConfig `json:"reachability,omitempty" yaml:"reachability,omitempty"` // Authentication optionally declares a named authentication diagnostic. // A supplied object requires Kind. - Authentication *AuthenticationProbeConfig + Authentication *AuthenticationProbeConfig `json:"authentication,omitempty" yaml:"authentication,omitempty"` } // ReachabilityProbeConfig configures an optional reachability destination. @@ -58,7 +58,7 @@ type ReachabilityProbeConfig struct { // Endpoint is an absolute HTTP(S) URL, including any desired path or query. // Nil selects the effective backend endpoint; an explicit blank value is // invalid. - Endpoint *string + Endpoint *string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"` } // AuthenticationProbeConfig configures an optional named authentication @@ -66,11 +66,11 @@ type ReachabilityProbeConfig struct { type AuthenticationProbeConfig struct { // Kind selects the authentication adapter. Supported values are "none" and // "openrouter_key"; surrounding whitespace and case are normalized. - Kind *string + Kind *string `json:"kind,omitempty" yaml:"kind,omitempty"` // Endpoint is an absolute HTTP(S) URL, including any desired path or query. // Nil selects the adapter's backend-relative destination; an explicit blank // value is invalid. - Endpoint *string + Endpoint *string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"` } // BackendSource creates a labeled ConfigKit mapping containing backend records diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 88e94ae..d7f7b88 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -229,6 +229,10 @@ filesystem adapter, recursive input converter, or inheritance resolver. ## Stage 1: Declare The Resource Result Contract +**Completed:** Public result fields and JSON/YAML tags reviewed against the +tables; compilation and encoding checks are deferred until the corresponding +projection and consumer migrations are complete. + **Scope:** Public inspection values and their nested representation only. 1. Read `types.go`, `backends.go`, and the current inspection GoDoc in `engine.go`. diff --git a/engine.go b/engine.go index 9f8874a..b7ca260 100644 --- a/engine.go +++ b/engine.go @@ -275,7 +275,7 @@ func NewEngine(cfg Config, opts ...Option) (*Engine, error) { // the selected captured definition; its spelling, length, // encoding, algorithm, and security properties are not contracts. // -// This method does not return prompt bodies, templates, source paths, schemas, +// This method does not return parsed templates, source paths, schemas, // rendered messages, or execution settings. It does not resolve a profile or // credential, read artifacts or schemas, render, validate, admit capacity, // contact a provider, or generate model output. The returned PromptInspection @@ -306,12 +306,10 @@ func (e *Engine) InspectPrompt( // starting execution work. // // InspectProfile looks up a nonblank profileID exactly and case-sensitively -// in the captured effective configuration. It applies the framework timeout -// baseline, selected -// backend, and then selected profile to EffectiveModelParams without a request -// override. BackendID is empty for an endpoint-only profile. +// in the captured effective configuration. It reports the resolved profile +// resource without backend completion, execution defaults, or request overrides. // -// APIKeyEnv in the returned target is an environment-variable name, never its +// APIKeyEnv in the returned resource is an environment-variable name, never its // value. APIKeyRequired reports that a credential is required; an explicit // profile environment source can also be present. InspectProfile neither derives // an ID from a prompt default_profile nor checks credential availability, so an diff --git a/resource_inspection.go b/resource_inspection.go new file mode 100644 index 0000000..4a12c97 --- /dev/null +++ b/resource_inspection.go @@ -0,0 +1,85 @@ +package promptkit + +// ProfileInspection describes a resolved profile resource, before backend +// completion or request overrides. References are not resolved. APIKeyEnv is +// an environment-variable name, never a credential value. The result and its +// mutable values are caller-owned. Nil pointers denote absent fields; non-nil +// pointers preserve explicit zero values and empty collections. JSON and YAML +// use the indicated field names and omit absent optional fields. +type ProfileInspection struct { + ProfileID string `json:"id" yaml:"id"` + Backend *string `json:"backend,omitempty" yaml:"backend,omitempty"` + Endpoint *string `json:"endpoint,omitempty" yaml:"endpoint,omitempty"` + Model *string `json:"model,omitempty" yaml:"model,omitempty"` + Temperature *float64 `json:"temperature,omitempty" yaml:"temperature,omitempty"` + TopP *float64 `json:"top_p,omitempty" yaml:"top_p,omitempty"` + MaxTokens *int `json:"max_tokens,omitempty" yaml:"max_tokens,omitempty"` + TimeoutSeconds *int `json:"timeout_seconds,omitempty" yaml:"timeout_seconds,omitempty"` + ServiceTier *string `json:"service_tier,omitempty" yaml:"service_tier,omitempty"` + ReasoningEffort *string `json:"reasoning_effort,omitempty" yaml:"reasoning_effort,omitempty"` + APIKeyEnv *string `json:"api_key_env,omitempty" yaml:"api_key_env,omitempty"` + APIKeyRequired *bool `json:"api_key_required,omitempty" yaml:"api_key_required,omitempty"` + ExtraParams *map[string]any `json:"extra_params,omitempty" yaml:"extra_params,omitempty"` +} + +// BackendInspection describes a resolved backend resource, not runtime capacity +// or diagnostic destinations derived during execution. APIKeyEnv names an +// environment variable, not its value. The result and its mutable values are +// caller-owned. Nil pointers denote absent fields; non-nil pointers preserve +// explicit zero values and empty collections in JSON and YAML. +type BackendInspection struct { + BackendID string `json:"id" yaml:"id"` + Endpoint string `json:"endpoint" yaml:"endpoint"` + APIKeyEnv *string `json:"api_key_env,omitempty" yaml:"api_key_env,omitempty"` + ConcurrencyLimit *int `json:"concurrency_limit,omitempty" yaml:"concurrency_limit,omitempty"` + QueueCapacity *int `json:"queue_capacity,omitempty" yaml:"queue_capacity,omitempty"` + ExtraParams *map[string]any `json:"extra_params,omitempty" yaml:"extra_params,omitempty"` + SmokeTests *BackendSmokeTestConfig `json:"smoke_tests,omitempty" yaml:"smoke_tests,omitempty"` +} + +// PromptInspection describes a resolved prompt resource. Messages contain +// captured inline or imported text, not rendered content. References are not +// resolved by inspection; PromptHash is opaque. The result and its mutable +// values are caller-owned. Nil pointers denote absent fields; non-nil pointers +// preserve explicit zero values and empty collections in JSON and YAML. +type PromptInspection struct { + PromptID string `json:"id" yaml:"id"` + PromptHash string `json:"prompt_hash" yaml:"prompt_hash"` + DefaultProfileID *string `json:"default_profile,omitempty" yaml:"default_profile,omitempty"` + Description *string `json:"description,omitempty" yaml:"description,omitempty"` + SessionID *string `json:"session_id,omitempty" yaml:"session_id,omitempty"` + Inputs *[]PromptInputInspection `json:"inputs,omitempty" yaml:"inputs,omitempty"` + Messages []PromptMessageInspection `json:"messages" yaml:"messages"` + OutputContract PromptOutputInspection `json:"output" yaml:"output"` +} + +// PromptInputInspection describes a declared input and its optional metadata. +type PromptInputInspection struct { + Name string `json:"name" yaml:"name"` + Required *bool `json:"required,omitempty" yaml:"required,omitempty"` + ContentType *string `json:"content_type,omitempty" yaml:"content_type,omitempty"` + Description *string `json:"description,omitempty" yaml:"description,omitempty"` +} + +// PromptMessageInspection describes a captured, unrendered message. +type PromptMessageInspection struct { + Role string `json:"role" yaml:"role"` + Content string `json:"content" yaml:"content"` + CacheControl *PromptCacheControlInspection `json:"cache_control,omitempty" yaml:"cache_control,omitempty"` +} + +// PromptCacheControlInspection describes configured message cache metadata. +// A non-nil TTL preserves an explicitly empty value. +type PromptCacheControlInspection struct { + Type CacheControlType `json:"type" yaml:"type"` + TTL *string `json:"ttl,omitempty" yaml:"ttl,omitempty"` +} + +// PromptOutputInspection describes a prompt's output contract. SchemaPath is +// a reference and is not loaded by inspection. +type PromptOutputInspection struct { + Format OutputFormat `json:"format" yaml:"format"` + ValidationMode ValidationMode `json:"validation_mode" yaml:"validation_mode"` + SchemaPath *string `json:"schema_path,omitempty" yaml:"schema_path,omitempty"` + RepairAttempts *int `json:"repair_attempts,omitempty" yaml:"repair_attempts,omitempty"` +} diff --git a/types.go b/types.go index 0ad4fa2..bff3378 100644 --- a/types.go +++ b/types.go @@ -356,27 +356,6 @@ type ExecutionTarget struct { ExtraParams map[string]any `json:"extra_params"` } -// ProfileInspection is the caller-owned result of [Engine.InspectProfile]. -// It has no stable JSON representation. -// -// EffectiveModelParams contains a copied effective target. APIKeyRequired is -// separate from that target to preserve ExecutionTarget's general execution -// and stable JSON contracts. -type ProfileInspection struct { - // ProfileID is the exact profile ID inspected by the engine. - ProfileID string - // EffectiveModelParams contains settings resolved from the framework timeout - // baseline, selected backend, and then profile, without a request override. - // Unset optional provider controls remain zero rather than reporting a - // provider default. APIKeyEnv is an environment-variable name, never its - // credential value. - EffectiveModelParams ExecutionTarget - // APIKeyRequired reports that a later execution must supply a usable direct - // key or environment credential. An explicit profile environment source can - // coexist with this requirement. - APIKeyRequired bool -} - // PromptInputDefinition describes one declared prompt input. // It has no stable JSON representation. type PromptInputDefinition struct { @@ -392,26 +371,6 @@ type PromptInputDefinition struct { Description string } -// PromptInspection is the caller-owned result of [Engine.InspectPrompt]. -// It has no stable JSON representation. -// -// Inputs contains copied declared input metadata in definition order. -// OutputContract is the normalized contract declared by the prompt definition, -// rather than a request-level effective override. PromptHash is opaque. -type PromptInspection struct { - // PromptID is the exact selected prompt ID after any namespace-view - // qualification. - PromptID string - // PromptHash is the opaque equality value for the selected definition. - PromptHash string - // DefaultProfileID is declared metadata and is not resolved by inspection. - DefaultProfileID string - // Inputs contains caller-owned declared input metadata in definition order. - Inputs []PromptInputDefinition - // OutputContract is the normalized contract declared by the definition. - OutputContract OutputContract -} - // ExecutionTargetOverride represents per-request runtime setting overrides and // has no stable JSON representation. //