130 lines
4.6 KiB
Go
130 lines
4.6 KiB
Go
|
|
package promptkit
|
||
|
|
|
||
|
|
import "go.maximumdirect.net/configkit"
|
||
|
|
|
||
|
|
// PromptConfig is a presence-aware source input for one prompt. Extends names
|
||
|
|
// a sibling prompt. Nil optional pointers and slices are omitted; non-nil
|
||
|
|
// pointers and slices preserve explicit zero, blank, and empty values. These
|
||
|
|
// inputs are mapping constructors, not serialized inspection values. Raw
|
||
|
|
// ConfigKit mappings can express explicit null and other composition controls.
|
||
|
|
type PromptConfig struct {
|
||
|
|
ID string
|
||
|
|
Extends, DefaultProfile, Description, SessionID *string
|
||
|
|
Inputs []PromptInputConfig
|
||
|
|
Messages []PromptMessageConfig
|
||
|
|
Output *PromptOutputConfig
|
||
|
|
}
|
||
|
|
|
||
|
|
// PromptInputConfig supplies an input declaration. Name is always supplied;
|
||
|
|
// nil optional pointers omit their fields.
|
||
|
|
type PromptInputConfig struct {
|
||
|
|
Name string
|
||
|
|
Required *bool
|
||
|
|
ContentType, Description *string
|
||
|
|
}
|
||
|
|
|
||
|
|
// PromptMessageConfig supplies message fields, including inline content or a
|
||
|
|
// content-file reference. Final content selection is validated by NewEngine.
|
||
|
|
type PromptMessageConfig struct {
|
||
|
|
Role, Content, ContentFile *string
|
||
|
|
CacheControl *PromptCacheControlConfig
|
||
|
|
}
|
||
|
|
|
||
|
|
// PromptCacheControlConfig supplies optional cache-control source fields.
|
||
|
|
type PromptCacheControlConfig struct{ Type, TTL *string }
|
||
|
|
|
||
|
|
// PromptOutputConfig supplies optional output contract source fields.
|
||
|
|
type PromptOutputConfig struct {
|
||
|
|
Format, ValidationMode, SchemaPath *string
|
||
|
|
RepairAttempts *int
|
||
|
|
}
|
||
|
|
|
||
|
|
// PromptSource creates a labeled ConfigKit mapping in caller order. Nil
|
||
|
|
// top-level input supplies an empty prompts sequence. Records may be partial:
|
||
|
|
// sibling inheritance and layered sources can complete them before NewEngine
|
||
|
|
// validates the final configuration. Mapping snapshots supported values when
|
||
|
|
// constructed; the helper neither resolves inheritance nor reads files.
|
||
|
|
// Relative content files use the ConfigKit Input filesystem context of the
|
||
|
|
// contributing field. Raw mappings remain available for explicit null and
|
||
|
|
// generic ConfigKit operations.
|
||
|
|
func PromptSource(label string, prompts []PromptConfig) configkit.Source {
|
||
|
|
definitions := make([]any, 0, len(prompts))
|
||
|
|
for _, config := range prompts {
|
||
|
|
fields := map[string]any{"id": config.ID}
|
||
|
|
if config.Extends != nil {
|
||
|
|
fields["extends"] = map[string]any{"id": *config.Extends}
|
||
|
|
}
|
||
|
|
if config.DefaultProfile != nil {
|
||
|
|
fields["default_profile"] = *config.DefaultProfile
|
||
|
|
}
|
||
|
|
if config.Description != nil {
|
||
|
|
fields["description"] = *config.Description
|
||
|
|
}
|
||
|
|
if config.SessionID != nil {
|
||
|
|
fields["session_id"] = *config.SessionID
|
||
|
|
}
|
||
|
|
if config.Inputs != nil {
|
||
|
|
inputs := make([]any, 0, len(config.Inputs))
|
||
|
|
for _, input := range config.Inputs {
|
||
|
|
item := map[string]any{"name": input.Name}
|
||
|
|
if input.Required != nil {
|
||
|
|
item["required"] = *input.Required
|
||
|
|
}
|
||
|
|
if input.ContentType != nil {
|
||
|
|
item["content_type"] = *input.ContentType
|
||
|
|
}
|
||
|
|
if input.Description != nil {
|
||
|
|
item["description"] = *input.Description
|
||
|
|
}
|
||
|
|
inputs = append(inputs, item)
|
||
|
|
}
|
||
|
|
fields["inputs"] = inputs
|
||
|
|
}
|
||
|
|
if config.Messages != nil {
|
||
|
|
messages := make([]any, 0, len(config.Messages))
|
||
|
|
for _, message := range config.Messages {
|
||
|
|
item := make(map[string]any)
|
||
|
|
if message.Role != nil {
|
||
|
|
item["role"] = *message.Role
|
||
|
|
}
|
||
|
|
if message.Content != nil {
|
||
|
|
item["content"] = *message.Content
|
||
|
|
}
|
||
|
|
if message.ContentFile != nil {
|
||
|
|
item["content_file"] = *message.ContentFile
|
||
|
|
}
|
||
|
|
if message.CacheControl != nil {
|
||
|
|
cache := make(map[string]any)
|
||
|
|
if message.CacheControl.Type != nil {
|
||
|
|
cache["type"] = *message.CacheControl.Type
|
||
|
|
}
|
||
|
|
if message.CacheControl.TTL != nil {
|
||
|
|
cache["ttl"] = *message.CacheControl.TTL
|
||
|
|
}
|
||
|
|
item["cache_control"] = cache
|
||
|
|
}
|
||
|
|
messages = append(messages, item)
|
||
|
|
}
|
||
|
|
fields["messages"] = messages
|
||
|
|
}
|
||
|
|
if config.Output != nil {
|
||
|
|
output := make(map[string]any)
|
||
|
|
if config.Output.Format != nil {
|
||
|
|
output["format"] = *config.Output.Format
|
||
|
|
}
|
||
|
|
if config.Output.ValidationMode != nil {
|
||
|
|
output["validation_mode"] = *config.Output.ValidationMode
|
||
|
|
}
|
||
|
|
if config.Output.SchemaPath != nil {
|
||
|
|
output["schema_path"] = *config.Output.SchemaPath
|
||
|
|
}
|
||
|
|
if config.Output.RepairAttempts != nil {
|
||
|
|
output["repair_attempts"] = *config.Output.RepairAttempts
|
||
|
|
}
|
||
|
|
fields["output"] = output
|
||
|
|
}
|
||
|
|
definitions = append(definitions, fields)
|
||
|
|
}
|
||
|
|
return configkit.Mapping(label, map[string]any{"prompts": definitions})
|
||
|
|
}
|