Skip to content

Commit e8345f4

Browse files
chore: add sys.chat.current
1 parent b26476b commit e8345f4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+233
-71
lines changed

pkg/builtin/builtin.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ var SafeTools = map[string]struct{}{
2929
"sys.abort": {},
3030
"sys.chat.finish": {},
3131
"sys.chat.history": {},
32+
"sys.chat.current": {},
3233
"sys.echo": {},
3334
"sys.prompt": {},
3435
"sys.time.now": {},
@@ -229,6 +230,15 @@ var tools = map[string]types.Tool{
229230
BuiltinFunc: SysChatHistory,
230231
},
231232
},
233+
"sys.chat.current": {
234+
ToolDef: types.ToolDef{
235+
Parameters: types.Parameters{
236+
Description: "Retrieves the current chat dialog",
237+
Arguments: types.ObjectSchema(),
238+
},
239+
BuiltinFunc: SysChatCurrent,
240+
},
241+
},
232242
"sys.context": {
233243
ToolDef: types.ToolDef{
234244
Parameters: types.Parameters{
@@ -715,6 +725,28 @@ func writeHistory(ctx *engine.Context) (result []engine.ChatHistoryCall) {
715725
return
716726
}
717727

728+
func SysChatCurrent(ctx context.Context, _ []string, _ string, _ chan<- string) (string, error) {
729+
engineContext, _ := engine.FromContext(ctx)
730+
731+
var call any
732+
if engineContext != nil && engineContext.CurrentReturn != nil && engineContext.CurrentReturn.State != nil {
733+
call = engine.ChatHistoryCall{
734+
ID: engineContext.ID,
735+
Tool: engineContext.Tool,
736+
Completion: engineContext.CurrentReturn.State.Completion,
737+
}
738+
} else {
739+
call = map[string]any{}
740+
}
741+
742+
data, err := json.Marshal(call)
743+
if err != nil {
744+
return invalidArgument("", err), nil
745+
}
746+
747+
return string(data), nil
748+
}
749+
718750
func SysChatFinish(_ context.Context, _ []string, input string, _ chan<- string) (string, error) {
719751
var params struct {
720752
Message string `json:"return,omitempty"`

pkg/cli/gptscript.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ func (r *GPTScript) Run(cmd *cobra.Command, args []string) (retErr error) {
467467
DefaultModel: r.DefaultModel,
468468
TrustedRepoPrefixes: []string{"github.com/gptscript-ai"},
469469
DisableCache: r.DisableCache,
470-
Input: strings.Join(args[1:], " "),
470+
Input: toolInput,
471471
CacheDir: r.CacheDir,
472472
SubTool: r.SubTool,
473473
Workspace: r.Workspace,

pkg/engine/engine.go

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ type CallResult struct {
5959
type commonContext struct {
6060
ID string `json:"id"`
6161
Tool types.Tool `json:"tool"`
62+
CurrentAgent types.ToolReference `json:"currentAgent,omitempty"`
6263
AgentGroup []types.ToolReference `json:"agentGroup,omitempty"`
6364
InputContext []InputContext `json:"inputContext"`
6465
ToolCategory ToolCategory `json:"toolCategory,omitempty"`
@@ -73,10 +74,11 @@ type CallContext struct {
7374

7475
type Context struct {
7576
commonContext
76-
Ctx context.Context
77-
Parent *Context
78-
LastReturn *Return
79-
Program *types.Program
77+
Ctx context.Context
78+
Parent *Context
79+
LastReturn *Return
80+
CurrentReturn *Return
81+
Program *types.Program
8082
// Input is saved only so that we can render display text, don't use otherwise
8183
Input string
8284
}
@@ -129,6 +131,18 @@ func (c *Context) ParentID() string {
129131
return c.Parent.ID
130132
}
131133

134+
func (c *Context) CurrentAgent() types.ToolReference {
135+
for _, ref := range c.AgentGroup {
136+
if ref.ToolID == c.Tool.ID {
137+
return ref
138+
}
139+
}
140+
if c.Parent != nil {
141+
return c.Parent.CurrentAgent()
142+
}
143+
return types.ToolReference{}
144+
}
145+
132146
func (c *Context) GetCallContext() *CallContext {
133147
var toolName string
134148
if c.Parent != nil {
@@ -143,12 +157,15 @@ func (c *Context) GetCallContext() *CallContext {
143157
}
144158
}
145159

146-
return &CallContext{
160+
result := &CallContext{
147161
commonContext: c.commonContext,
148162
ParentID: c.ParentID(),
149163
ToolName: toolName,
150164
DisplayText: types.ToDisplayText(c.Tool, c.Input),
151165
}
166+
167+
result.CurrentAgent = c.CurrentAgent()
168+
return result
152169
}
153170

154171
func (c *Context) UnmarshalJSON([]byte) error {
@@ -215,10 +232,11 @@ func (c *Context) SubCallContext(ctx context.Context, input, toolID, callID stri
215232
AgentGroup: agentGroup,
216233
ToolCategory: toolCategory,
217234
},
218-
Ctx: ctx,
219-
Parent: c,
220-
Program: c.Program,
221-
Input: input,
235+
Ctx: ctx,
236+
Parent: c,
237+
Program: c.Program,
238+
CurrentReturn: c.CurrentReturn,
239+
Input: input,
222240
}, nil
223241
}
224242

@@ -270,6 +288,7 @@ func (e *Engine) Start(ctx Context, input string) (ret *Return, _ error) {
270288
MaxTokens: tool.Parameters.MaxTokens,
271289
JSONResponse: tool.Parameters.JSONResponse,
272290
Cache: tool.Parameters.Cache,
291+
Chat: tool.Parameters.Chat,
273292
Temperature: tool.Parameters.Temperature,
274293
InternalSystemPrompt: tool.Parameters.InternalPrompt,
275294
}

pkg/openai/client.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,11 +300,16 @@ func (c *Client) Call(ctx context.Context, messageRequest types.CompletionReques
300300
if messageRequest.Model == "" {
301301
messageRequest.Model = c.defaultModel
302302
}
303+
303304
msgs, err := toMessages(messageRequest, !c.setSeed)
304305
if err != nil {
305306
return nil, err
306307
}
307308

309+
if messageRequest.Chat {
310+
msgs = dropMessagesOverCount(messageRequest.MaxTokens, msgs)
311+
}
312+
308313
if len(msgs) == 0 {
309314
log.Errorf("invalid request, no messages to send to LLM")
310315
return &types.CompletionMessage{

pkg/openai/count.go

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package openai
2+
3+
import openai "github.com/gptscript-ai/chat-completion-client"
4+
5+
func dropMessagesOverCount(maxTokens int, msgs []openai.ChatCompletionMessage) (result []openai.ChatCompletionMessage) {
6+
var (
7+
lastSystem int
8+
withinBudget int
9+
budget = maxTokens
10+
)
11+
12+
if maxTokens == 0 {
13+
budget = 300_000
14+
} else {
15+
budget *= 3
16+
}
17+
18+
for i, msg := range msgs {
19+
if msg.Role == openai.ChatMessageRoleSystem {
20+
budget -= countMessage(msg)
21+
lastSystem = i
22+
result = append(result, msg)
23+
} else {
24+
break
25+
}
26+
}
27+
28+
for i := len(msgs) - 1; i > lastSystem; i-- {
29+
withinBudget = i
30+
budget -= countMessage(msgs[i])
31+
if budget <= 0 {
32+
break
33+
}
34+
}
35+
36+
if withinBudget == len(msgs)-1 {
37+
// We are going to drop all non system messages, which seems useless, so just return them
38+
// all and let it fail
39+
return msgs
40+
}
41+
42+
return append(result, msgs[withinBudget:]...)
43+
}
44+
45+
func countMessage(msg openai.ChatCompletionMessage) (count int) {
46+
count += len(msg.Role)
47+
count += len(msg.Content)
48+
for _, content := range msg.MultiContent {
49+
count += len(content.Text)
50+
}
51+
for _, tool := range msg.ToolCalls {
52+
count += len(tool.Function.Name)
53+
count += len(tool.Function.Arguments)
54+
}
55+
count += len(msg.ToolCallID)
56+
return count / 3
57+
}

pkg/runner/output.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ func (r *Runner) handleOutput(callCtx engine.Context, monitor Monitor, env []str
4141
for _, outputToolRef := range outputToolRefs {
4242
inputData, err := json.Marshal(map[string]any{
4343
"output": output,
44-
"chatFinish": chatFinish,
4544
"continuation": continuation,
4645
"chat": callCtx.Tool.Chat,
4746
})

pkg/runner/runner.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,8 @@ func (r *Runner) resume(callCtx engine.Context, monitor Monitor, env []string, s
559559
}
560560

561561
for {
562+
callCtx.CurrentReturn = state.Continuation
563+
562564
if state.Continuation.Result != nil && len(state.Continuation.Calls) == 0 && state.SubCallID == "" && state.ResumeInput == nil {
563565
progressClose()
564566
monitor.Event(Event{

pkg/tests/runner_test.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,8 @@ func TestSubChat(t *testing.T) {
413413
],
414414
"usage": {}
415415
}
416-
]
416+
],
417+
"chat": true
417418
}
418419
},
419420
"result": "Assistant 1"
@@ -555,7 +556,8 @@ func TestSubChat(t *testing.T) {
555556
],
556557
"usage": {}
557558
}
558-
]
559+
],
560+
"chat": true
559561
}
560562
},
561563
"result": "Assistant 2"
@@ -622,7 +624,8 @@ func TestChat(t *testing.T) {
622624
],
623625
"usage": {}
624626
}
625-
]
627+
],
628+
"chat": true
626629
}
627630
},
628631
"result": "Assistant 1"
@@ -691,7 +694,8 @@ func TestChat(t *testing.T) {
691694
],
692695
"usage": {}
693696
}
694-
]
697+
],
698+
"chat": true
695699
}
696700
},
697701
"result": "Assistant 2"
@@ -866,7 +870,7 @@ func TestOutput(t *testing.T) {
866870
require.NoError(t, err)
867871
r.AssertResponded(t)
868872
assert.False(t, resp.Done)
869-
autogold.Expect(`CHAT: true CONTENT: Response 1 CONTINUATION: true FINISH: false suffix
873+
autogold.Expect(`CHAT: true CONTENT: Response 1 CONTINUATION: true suffix
870874
`).Equal(t, resp.Content)
871875
autogold.ExpectFile(t, toJSONString(t, resp), autogold.Name(t.Name()+"/step1"))
872876

@@ -877,7 +881,7 @@ func TestOutput(t *testing.T) {
877881
require.NoError(t, err)
878882
r.AssertResponded(t)
879883
assert.False(t, resp.Done)
880-
autogold.Expect(`CHAT: true CONTENT: Response 2 CONTINUATION: true FINISH: false suffix
884+
autogold.Expect(`CHAT: true CONTENT: Response 2 CONTINUATION: true suffix
881885
`).Equal(t, resp.Content)
882886
autogold.ExpectFile(t, toJSONString(t, resp), autogold.Name(t.Name()+"/step2"))
883887

@@ -890,7 +894,7 @@ func TestOutput(t *testing.T) {
890894
require.NoError(t, err)
891895
r.AssertResponded(t)
892896
assert.True(t, resp.Done)
893-
autogold.Expect(`CHAT FINISH: CHAT: true CONTENT: Chat Done CONTINUATION: false FINISH: true suffix
897+
autogold.Expect(`CHAT FINISH: CHAT: true CONTENT: Chat Done CONTINUATION: false suffix
894898
`).Equal(t, resp.Content)
895899
autogold.ExpectFile(t, toJSONString(t, resp), autogold.Name(t.Name()+"/step3"))
896900
}

pkg/tests/testdata/TestAgents/call1.golden

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,6 @@
5252
],
5353
"usage": {}
5454
}
55-
]
55+
],
56+
"chat": true
5657
}`

pkg/tests/testdata/TestAgents/call2.golden

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@
2828
],
2929
"usage": {}
3030
}
31-
]
31+
],
32+
"chat": true
3233
}`

pkg/tests/testdata/TestAgents/call3.golden

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,6 @@
4343
],
4444
"usage": {}
4545
}
46-
]
46+
],
47+
"chat": true
4748
}`

pkg/tests/testdata/TestAgents/call4.golden

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,6 @@
1111
],
1212
"usage": {}
1313
}
14-
]
14+
],
15+
"chat": true
1516
}`

pkg/tests/testdata/TestAgents/step1.golden

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,8 @@
7575
],
7676
"usage": {}
7777
}
78-
]
78+
],
79+
"chat": true
7980
},
8081
"pending": {
8182
"call_1": {
@@ -145,7 +146,8 @@
145146
],
146147
"usage": {}
147148
}
148-
]
149+
],
150+
"chat": true
149151
},
150152
"pending": {
151153
"call_2": {
@@ -230,7 +232,8 @@
230232
],
231233
"usage": {}
232234
}
233-
]
235+
],
236+
"chat": true
234237
},
235238
"pending": {
236239
"call_3": {
@@ -277,7 +280,8 @@
277280
],
278281
"usage": {}
279282
}
280-
]
283+
],
284+
"chat": true
281285
}
282286
},
283287
"result": "TEST RESULT CALL: 4"

pkg/tests/testdata/TestChat/call1.golden

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@
2020
],
2121
"usage": {}
2222
}
23-
]
23+
],
24+
"chat": true
2425
}`

pkg/tests/testdata/TestChat/call2.golden

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,6 @@
3838
],
3939
"usage": {}
4040
}
41-
]
41+
],
42+
"chat": true
4243
}`

0 commit comments

Comments
 (0)