-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathgoal.go
More file actions
105 lines (83 loc) · 3 KB
/
Copy pathgoal.go
File metadata and controls
105 lines (83 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package cogito
import (
"fmt"
"github.com/mudler/cogito/prompt"
"github.com/mudler/cogito/structures"
"github.com/mudler/xlog"
)
// ExtractGoal extracts a goal from a conversation
func ExtractGoal(llm LLM, f Fragment, opts ...Option) (*structures.Goal, error) {
o := defaultOptions()
o.Apply(opts...)
// First we ask the LLM if there is a goal from the conversation
prompter := o.prompts.GetPrompt(prompt.PromptIdentifyGoalType)
goalIdentifierOptions := struct {
Context string
AdditionalContext string
}{
Context: f.String(),
}
if o.deepContext && f.ParentFragment != nil {
goalIdentifierOptions.AdditionalContext = f.ParentFragment.AllFragmentsStrings()
}
prompt, err := prompter.Render(goalIdentifierOptions)
if err != nil {
return nil, fmt.Errorf("failed to render tool reasoner prompt: %w", err)
}
goalConv := NewEmptyFragment().AddMessage("user", prompt)
reasoningGoal, err := llm.Ask(o.context, goalConv)
if err != nil {
return nil, fmt.Errorf("failed to ask LLM for goal identification: %w", err)
}
identifiedGoal := reasoningGoal.LastMessage()
structure, goal := structures.StructureGoal()
goalConv = NewEmptyFragment().AddMessage("user", identifiedGoal.Content)
err = goalConv.ExtractStructure(o.context, llm, structure)
if err != nil {
return nil, fmt.Errorf("failed to extract boolean structure: %w", err)
}
return goal, nil
}
// IsGoalAchieved checks if a goal has been achieved
func IsGoalAchieved(llm LLM, f Fragment, goal *structures.Goal, opts ...Option) (*structures.Boolean, error) {
o := defaultOptions()
o.Apply(opts...)
// First we ask the LLM if there is a goal from the conversation
prompter := o.prompts.GetPrompt(prompt.PromptGoalAchievedType)
goalAchievedOpts := struct {
Context string
AdditionalContext string
Goal string
FeedbackConversation string
}{
Context: f.String(),
}
if goal != nil {
goalAchievedOpts.Goal = goal.Goal
}
if o.deepContext && f.ParentFragment != nil {
goalAchievedOpts.AdditionalContext = f.ParentFragment.AllFragmentsStrings()
}
var feedbackConv *Fragment
if o.feedbackCallback != nil {
feedbackConv = o.feedbackCallback()
goalAchievedOpts.FeedbackConversation = feedbackConv.String()
}
prompt, err := prompter.Render(goalAchievedOpts)
if err != nil {
return nil, fmt.Errorf("failed to render tool reasoner prompt: %w", err)
}
multimedias := []Multimedia{}
if feedbackConv != nil {
multimedias = feedbackConv.Multimedia
}
goalAchievedConv := NewEmptyFragment().AddMessage("user", prompt, multimedias...)
reasoningGoal, err := llm.Ask(o.context, goalAchievedConv)
if err != nil {
return nil, fmt.Errorf("failed to ask LLM for goal identification: %w", err)
}
boolConv := NewEmptyFragment().AddMessage("user", reasoningGoal.LastMessage().Content)
xlog.Debug("Check if goal is achieved in current conversation", "reasoning", reasoningGoal.LastMessage().Content)
/// XXX: ExtractBoolean seems to be really brittle
return ExtractBoolean(llm, boolConv, opts...)
}