Add collection migration example and guide

This commit is contained in:
2026-10-17 06:29:57 +00:00
parent 8669294cf6
commit 29f104fbc0
12 changed files with 356 additions and 26 deletions

View File

@@ -0,0 +1,17 @@
backends:
offline:
endpoint: https://review.example.invalid/v1
profiles:
audit:
backend: review/offline
model: review-model
prompts:
check:
default_profile: review/audit
description: Inspect a review item without contacting a model provider.
messages:
- role: user
content: Review the supplied synthetic example.
output:
format: text
validation_mode: none

View File

@@ -0,0 +1,5 @@
version: "1"
configkit:
imports:
- path: fragments/resources.yaml
release_version: "1.4.0"

View File

@@ -1,7 +1,18 @@
backends:
offline:
endpoint: https://example.invalid/v1
profiles:
base:
backend: support/offline
model: offline-model
timeout_seconds: 90
fast:
extends: base
timeout_seconds: 60
prompts:
example.prepare:
prepare:
version: "1.0.0"
default_profile: offline-example
default_profile: support/fast
description: Prepare a prompt without contacting a model provider.
inputs:
- name: note
@@ -11,7 +22,7 @@ prompts:
- role: system
content: Summarize the note in one sentence.
- role: user
content: '{{input "note"}}'
content_file: ../messages/note.md
output:
format: text
validation_mode: basic

View File

@@ -0,0 +1 @@
{{input "note"}}

View File

@@ -0,0 +1,4 @@
# A later input intentionally replaces only the inherited profile timeout.
profiles:
fast:
timeout_seconds: 30

View File

@@ -11,33 +11,72 @@ import (
)
type summary struct {
PromptID string `json:"prompt_id"`
PromptVersion *string `json:"prompt_version,omitempty"`
SelectedProfile string `json:"selected_profile"`
Model string `json:"model"`
MessageCount int `json:"message_count"`
PromptID string `json:"prompt_id"`
PromptVersion *string `json:"prompt_version,omitempty"`
SelectedProfile string `json:"selected_profile"`
Model string `json:"model"`
MessageCount int `json:"message_count"`
ProfileTimeout int `json:"profile_timeout_seconds"`
Namespaces []string `json:"namespaces"`
Collections []collectionSummary `json:"collections"`
ScopedPrompts []string `json:"scoped_prompts"`
ReviewPrompts []string `json:"review_prompts"`
}
type collectionSummary struct {
Namespace string `json:"namespace"`
ReleaseVersion *string `json:"release_version"`
}
func main() {
endpoint, model := "https://example.invalid/v1", "offline-model"
support, err := promptkit.CollectionInput(
"support",
configkit.File("examples/go-library/prepare/collections/support/collection.yaml"),
)
if err != nil {
exit(err)
}
review, err := promptkit.CollectionInput(
"review",
configkit.File("examples/go-library/prepare/collections/review/collection.yaml"),
)
if err != nil {
exit(err)
}
override, err := promptkit.CollectionInput(
"support",
configkit.File("examples/go-library/prepare/collections/support/operator-overrides.yaml"),
)
if err != nil {
exit(err)
}
engine, err := promptkit.NewEngine(promptkit.Config{Sources: promptkit.ConfigurationSources{
Underlays: []configkit.Underlay{{Inputs: []configkit.Input{{Source: promptkit.ProfileSource("example profile", map[string]promptkit.ProfileConfig{
"offline-example": {Endpoint: &endpoint, Model: &model},
})}}}},
Main: &configkit.Input{Source: configkit.File("examples/go-library/prepare/prompt.yaml")},
Underlays: []configkit.Underlay{
{Inputs: []configkit.Input{support, review}},
{Inputs: []configkit.Input{override}},
},
}})
if err != nil {
exit(err)
}
ctx := context.Background()
scoped, err := engine.WithNamespaces(promptkit.Namespaces{
Prompt: "support", Profile: "support", Backend: "support",
})
if err != nil {
exit(err)
}
view, err := engine.InspectConfiguration()
if err != nil {
exit(err)
}
if _, found := view.Explain(configkit.Keys("profiles", "offline-example", "model")); !found {
exit(fmt.Errorf("configured profile model was not found"))
if _, found := view.Explain(configkit.Keys(
"collections", "support", "profiles", "fast", "timeout_seconds",
)); !found {
exit(fmt.Errorf("collection profile override was not found"))
}
requirements, err := engine.InspectRequirements(context.Background(), promptkit.RequirementInspectionRequest{
PromptID: "example.prepare",
requirements, err := scoped.InspectRequirements(ctx, promptkit.RequirementInspectionRequest{
PromptID: "prepare",
})
if err != nil {
exit(err)
@@ -49,18 +88,61 @@ func main() {
}
request := promptkit.RunRequest{
PromptID: "example.prepare",
PromptID: "prepare",
ProfileID: "fast",
Inputs: map[string]promptkit.ArtifactRef{
"note": promptkit.Inline("Ada finished the migration review."),
},
}
if err := engine.ValidateRequest(context.Background(), request); err != nil {
if err := scoped.ValidateRequest(ctx, request); err != nil {
exit(err)
}
prepared, err := engine.Prepare(context.Background(), request)
prepared, err := scoped.Prepare(ctx, request)
if err != nil {
exit(err)
}
profile, err := scoped.InspectProfile(ctx, "fast")
if err != nil {
exit(err)
}
if profile.EffectiveModelParams.TimeoutSeconds != 30 {
exit(fmt.Errorf(
"later profile override was not applied: timeout is %d seconds",
profile.EffectiveModelParams.TimeoutSeconds,
))
}
namespaces, err := scoped.ListNamespaces(ctx)
if err != nil {
exit(err)
}
collections, err := scoped.ListCollections(ctx)
if err != nil {
exit(err)
}
scopedPrompts, err := scoped.ListPrompts(ctx)
if err != nil {
exit(err)
}
reviewPrompts, err := scoped.ListPrompts(ctx, promptkit.NamespaceFilter{
Mode: promptkit.NamespaceNamed, Name: "review",
})
if err != nil {
exit(err)
}
scopedPromptIDs := make([]string, len(scopedPrompts))
for index := range scopedPrompts {
scopedPromptIDs[index] = scopedPrompts[index].ID
}
reviewPromptIDs := make([]string, len(reviewPrompts))
for index := range reviewPrompts {
reviewPromptIDs[index] = reviewPrompts[index].ID
}
collectionSummaries := make([]collectionSummary, len(collections))
for index := range collections {
collectionSummaries[index] = collectionSummary{
Namespace: collections[index].Namespace, ReleaseVersion: collections[index].ReleaseVersion,
}
}
encoder := json.NewEncoder(os.Stdout)
encoder.SetIndent("", " ")
@@ -70,6 +152,11 @@ func main() {
SelectedProfile: prepared.SelectedProfileID,
Model: prepared.EffectiveModelParams.Model,
MessageCount: len(prepared.Messages),
ProfileTimeout: profile.EffectiveModelParams.TimeoutSeconds,
Namespaces: namespaces,
Collections: collectionSummaries,
ScopedPrompts: scopedPromptIDs,
ReviewPrompts: reviewPromptIDs,
}); err != nil {
exit(err)
}