package agent import ( "fmt" "strings" "github.com/sipeed/picoclaw/pkg/providers" ) func promptBuildRequestForTurn( ts *turnState, history []providers.Message, summary string, currentMessage string, media []string, ) PromptBuildRequest { return PromptBuildRequest{ History: history, Summary: summary, CurrentMessage: currentMessage, Media: append([]string(nil), media...), Channel: ts.channel, ChatID: ts.chatID, SenderID: ts.opts.Dispatch.SenderID(), SenderDisplayName: ts.opts.SenderDisplayName, ActiveSkills: activeSkillNames(ts.agent, ts.opts), Overlays: promptOverlaysForOptions(ts.opts), } } func promptOverlaysForOptions(opts processOptions) []PromptPart { systemPrompt := strings.TrimSpace(opts.SystemPromptOverride) if systemPrompt == "" { return nil } return []PromptPart{ { ID: "instruction.subturn_profile", Layer: PromptLayerInstruction, Slot: PromptSlotWorkspace, Source: PromptSource{ID: PromptSourceSubTurnProfile, Name: "subturn.profile"}, Title: "SubTurn System Instructions", Content: systemPrompt, Stable: false, Cache: PromptCacheNone, }, } } func promptContentBlock(part PromptPart, cache *providers.CacheControl) providers.ContentBlock { if cache == nil { cache = cacheControlForPromptPart(part) } return providers.ContentBlock{ Type: "text", Text: part.Content, CacheControl: cache, PromptLayer: string(part.Layer), PromptSlot: string(part.Slot), PromptSource: string(part.Source.ID), } } func cacheControlForPromptPart(part PromptPart) *providers.CacheControl { switch part.Cache { case PromptCacheEphemeral: return &providers.CacheControl{Type: "ephemeral"} default: return nil } } func promptMessageWithMetadata( msg providers.Message, layer PromptLayer, slot PromptSlot, source PromptSourceID, ) providers.Message { msg.PromptLayer = string(layer) msg.PromptSlot = string(slot) msg.PromptSource = string(source) return msg } func promptMessageWithDefaultMetadata( msg providers.Message, layer PromptLayer, slot PromptSlot, source PromptSourceID, ) providers.Message { if strings.TrimSpace(msg.PromptSource) != "" { return msg } return promptMessageWithMetadata(msg, layer, slot, source) } func userPromptMessage(content string, media []string) providers.Message { msg := providers.Message{ Role: "user", Content: content, } if len(media) > 0 { msg.Media = append([]string(nil), media...) } return promptMessageWithMetadata(msg, PromptLayerTurn, PromptSlotMessage, PromptSourceUserMessage) } func steeringPromptMessage(msg providers.Message) providers.Message { return promptMessageWithDefaultMetadata(msg, PromptLayerTurn, PromptSlotSteering, PromptSourceSteering) } func subTurnResultPromptMessage(content string) providers.Message { return promptMessageWithMetadata( providers.Message{Role: "user", Content: fmt.Sprintf("[SubTurn Result] %s", content)}, PromptLayerTurn, PromptSlotSubTurn, PromptSourceSubTurnResult, ) } func interruptPromptMessage(content string) providers.Message { return promptMessageWithMetadata( providers.Message{Role: "user", Content: content}, PromptLayerTurn, PromptSlotInterrupt, PromptSourceInterrupt, ) }