From dcd335dc683dc1efd375ed422228f026f354964c Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Mon, 1 Sep 2025 16:07:59 +0700 Subject: [PATCH 1/3] Add createdAt for chat.Message Signed-off-by: Trung Nguyen --- cmd/root/run.go | 1 + pkg/chat/chat.go | 8 +++++++- pkg/runtime/runtime.go | 5 +++++ pkg/session/session.go | 30 ++++++++++++++++++------------ 4 files changed, 31 insertions(+), 13 deletions(-) diff --git a/cmd/root/run.go b/cmd/root/run.go index 9d60391ad..644444c1a 100644 --- a/cmd/root/run.go +++ b/cmd/root/run.go @@ -578,6 +578,7 @@ func createUserMessageWithAttachment(agentFilename, userContent, attachmentPath Message: chat.Message{ Role: chat.MessageRoleUser, MultiContent: multiContent, + CreatedAt: time.Now(), }, } } diff --git a/pkg/chat/chat.go b/pkg/chat/chat.go index e5b03ce41..a17c22374 100644 --- a/pkg/chat/chat.go +++ b/pkg/chat/chat.go @@ -1,6 +1,10 @@ package chat -import "github.com/docker/cagent/pkg/tools" +import ( + "time" + + "github.com/docker/cagent/pkg/tools" +) type MessageRole string @@ -56,6 +60,8 @@ type Message struct { // For Role=tool prompts this should be set to the ID given in the assistant's prior request to call a tool. ToolCallID string `json:"tool_call_id,omitempty"` + + CreatedAt time.Time `json:"created_at"` } type MessagePart struct { diff --git a/pkg/runtime/runtime.go b/pkg/runtime/runtime.go index 42e80c08c..c1d898ad6 100644 --- a/pkg/runtime/runtime.go +++ b/pkg/runtime/runtime.go @@ -8,6 +8,7 @@ import ( "io" "log/slog" "strings" + "time" "github.com/docker/cagent/pkg/agent" "github.com/docker/cagent/pkg/chat" @@ -223,6 +224,7 @@ func (r *Runtime) RunStream(ctx context.Context, sess *session.Session) <-chan E Role: chat.MessageRoleAssistant, Content: content, ToolCalls: calls, + CreatedAt: time.Now(), } sess.AddMessage(session.NewAgentMessage(a, &assistantMessage)) @@ -544,6 +546,7 @@ func (r *Runtime) runTool(ctx context.Context, tool tools.Tool, toolCall tools.T Role: chat.MessageRoleTool, Content: res.Output, ToolCallID: toolCall.ID, + CreatedAt: time.Now(), } sess.AddMessage(session.NewAgentMessage(a, &toolResponseMsg)) } @@ -584,6 +587,7 @@ func (r *Runtime) runAgentTool(ctx context.Context, handler ToolHandler, sess *s Role: chat.MessageRoleTool, Content: output, ToolCallID: toolCall.ID, + CreatedAt: time.Now(), } sess.AddMessage(session.NewAgentMessage(a, &toolResponseMsg)) } @@ -614,6 +618,7 @@ func (r *Runtime) addToolCancelledResponse(sess *session.Session, toolCall tools Role: chat.MessageRoleTool, Content: result, ToolCallID: toolCall.ID, + CreatedAt: time.Now(), } sess.AddMessage(session.NewAgentMessage(a, &toolResponseMsg)) } diff --git a/pkg/session/session.go b/pkg/session/session.go index 10fd13e6e..ea43866c6 100644 --- a/pkg/session/session.go +++ b/pkg/session/session.go @@ -74,8 +74,9 @@ func UserMessage(agentFilename, content string) *Message { AgentFilename: agentFilename, AgentName: "", Message: chat.Message{ - Role: chat.MessageRoleUser, - Content: content, + Role: chat.MessageRoleUser, + Content: content, + CreatedAt: time.Now(), }, } } @@ -93,8 +94,9 @@ func SystemMessage(content string) *Message { AgentFilename: "", AgentName: "", Message: chat.Message{ - Role: chat.MessageRoleSystem, - Content: content, + Role: chat.MessageRoleSystem, + Content: content, + CreatedAt: time.Now(), }, } } @@ -199,8 +201,9 @@ func (s *Session) GetMessages(a *agent.Agent) []chat.Message { } messages = append(messages, chat.Message{ - Role: "system", - Content: "You are a multi-agent system, make sure to answer the user query in the most helpful way possible. You have access to these sub-agents:\n" + subAgentsStr + "\nIMPORTANT: You can ONLY transfer tasks to the agents listed above using their ID. The valid agent IDs are: " + strings.Join(validAgentIDs, ", ") + ". You MUST NOT attempt to transfer to any other agent IDs - doing so will cause system errors.\n\nIf you are the best to answer the question according to your description, you can answer it.\n\nIf another agent is better for answering the question according to its description, call `transfer_task` function to transfer the question to that agent using the agent's ID. When transferring, do not generate any text other than the function call.\n\n", + Role: "system", + Content: "You are a multi-agent system, make sure to answer the user query in the most helpful way possible. You have access to these sub-agents:\n" + subAgentsStr + "\nIMPORTANT: You can ONLY transfer tasks to the agents listed above using their ID. The valid agent IDs are: " + strings.Join(validAgentIDs, ", ") + ". You MUST NOT attempt to transfer to any other agent IDs - doing so will cause system errors.\n\nIf you are the best to answer the question according to your description, you can answer it.\n\nIf another agent is better for answering the question according to its description, call `transfer_task` function to transfer the question to that agent using the agent's ID. When transferring, do not generate any text other than the function call.\n\n", + CreatedAt: time.Now(), }) } @@ -210,15 +213,17 @@ func (s *Session) GetMessages(a *agent.Agent) []chat.Message { } messages = append(messages, chat.Message{ - Role: chat.MessageRoleSystem, - Content: a.Instruction() + "\n\n" + date, + Role: chat.MessageRoleSystem, + Content: a.Instruction() + "\n\n" + date, + CreatedAt: time.Now(), }) for _, tool := range a.ToolSets() { if tool.Instructions() != "" { messages = append(messages, chat.Message{ - Role: chat.MessageRoleSystem, - Content: tool.Instructions(), + Role: chat.MessageRoleSystem, + Content: tool.Instructions(), + CreatedAt: time.Now(), }) } } @@ -233,8 +238,9 @@ func (s *Session) GetMessages(a *agent.Agent) []chat.Message { if lastSummaryIndex != -1 { messages = append(messages, chat.Message{ - Role: chat.MessageRoleSystem, - Content: "Session Summary: " + s.Messages[lastSummaryIndex].Summary, + Role: chat.MessageRoleSystem, + Content: "Session Summary: " + s.Messages[lastSummaryIndex].Summary, + CreatedAt: time.Now(), }) } From 78ebf9a20e0c8c110908c007c43c399501007cb5 Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Mon, 1 Sep 2025 17:28:29 +0700 Subject: [PATCH 2/3] Using string for CreatedAt instead of Time Signed-off-by: Trung Nguyen --- cmd/root/run.go | 2 +- pkg/chat/chat.go | 5 ++--- pkg/runtime/runtime.go | 8 ++++---- pkg/session/session.go | 12 ++++++------ 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/cmd/root/run.go b/cmd/root/run.go index 644444c1a..5137d5eb6 100644 --- a/cmd/root/run.go +++ b/cmd/root/run.go @@ -578,7 +578,7 @@ func createUserMessageWithAttachment(agentFilename, userContent, attachmentPath Message: chat.Message{ Role: chat.MessageRoleUser, MultiContent: multiContent, - CreatedAt: time.Now(), + CreatedAt: time.Now().Format(time.RFC3339), }, } } diff --git a/pkg/chat/chat.go b/pkg/chat/chat.go index a17c22374..78b107188 100644 --- a/pkg/chat/chat.go +++ b/pkg/chat/chat.go @@ -1,8 +1,6 @@ package chat import ( - "time" - "github.com/docker/cagent/pkg/tools" ) @@ -61,7 +59,8 @@ type Message struct { // For Role=tool prompts this should be set to the ID given in the assistant's prior request to call a tool. ToolCallID string `json:"tool_call_id,omitempty"` - CreatedAt time.Time `json:"created_at"` + // CreatedAt is the time the message was created + CreatedAt string `json:"created_at,omitempty"` } type MessagePart struct { diff --git a/pkg/runtime/runtime.go b/pkg/runtime/runtime.go index c1d898ad6..02285ad39 100644 --- a/pkg/runtime/runtime.go +++ b/pkg/runtime/runtime.go @@ -224,7 +224,7 @@ func (r *Runtime) RunStream(ctx context.Context, sess *session.Session) <-chan E Role: chat.MessageRoleAssistant, Content: content, ToolCalls: calls, - CreatedAt: time.Now(), + CreatedAt: time.Now().Format(time.RFC3339), } sess.AddMessage(session.NewAgentMessage(a, &assistantMessage)) @@ -546,7 +546,7 @@ func (r *Runtime) runTool(ctx context.Context, tool tools.Tool, toolCall tools.T Role: chat.MessageRoleTool, Content: res.Output, ToolCallID: toolCall.ID, - CreatedAt: time.Now(), + CreatedAt: time.Now().Format(time.RFC3339), } sess.AddMessage(session.NewAgentMessage(a, &toolResponseMsg)) } @@ -587,7 +587,7 @@ func (r *Runtime) runAgentTool(ctx context.Context, handler ToolHandler, sess *s Role: chat.MessageRoleTool, Content: output, ToolCallID: toolCall.ID, - CreatedAt: time.Now(), + CreatedAt: time.Now().Format(time.RFC3339), } sess.AddMessage(session.NewAgentMessage(a, &toolResponseMsg)) } @@ -618,7 +618,7 @@ func (r *Runtime) addToolCancelledResponse(sess *session.Session, toolCall tools Role: chat.MessageRoleTool, Content: result, ToolCallID: toolCall.ID, - CreatedAt: time.Now(), + CreatedAt: time.Now().Format(time.RFC3339), } sess.AddMessage(session.NewAgentMessage(a, &toolResponseMsg)) } diff --git a/pkg/session/session.go b/pkg/session/session.go index ea43866c6..f7fa11b74 100644 --- a/pkg/session/session.go +++ b/pkg/session/session.go @@ -76,7 +76,7 @@ func UserMessage(agentFilename, content string) *Message { Message: chat.Message{ Role: chat.MessageRoleUser, Content: content, - CreatedAt: time.Now(), + CreatedAt: time.Now().Format(time.RFC3339), }, } } @@ -96,7 +96,7 @@ func SystemMessage(content string) *Message { Message: chat.Message{ Role: chat.MessageRoleSystem, Content: content, - CreatedAt: time.Now(), + CreatedAt: time.Now().Format(time.RFC3339), }, } } @@ -203,7 +203,7 @@ func (s *Session) GetMessages(a *agent.Agent) []chat.Message { messages = append(messages, chat.Message{ Role: "system", Content: "You are a multi-agent system, make sure to answer the user query in the most helpful way possible. You have access to these sub-agents:\n" + subAgentsStr + "\nIMPORTANT: You can ONLY transfer tasks to the agents listed above using their ID. The valid agent IDs are: " + strings.Join(validAgentIDs, ", ") + ". You MUST NOT attempt to transfer to any other agent IDs - doing so will cause system errors.\n\nIf you are the best to answer the question according to your description, you can answer it.\n\nIf another agent is better for answering the question according to its description, call `transfer_task` function to transfer the question to that agent using the agent's ID. When transferring, do not generate any text other than the function call.\n\n", - CreatedAt: time.Now(), + CreatedAt: time.Now().Format(time.RFC3339), }) } @@ -215,7 +215,7 @@ func (s *Session) GetMessages(a *agent.Agent) []chat.Message { messages = append(messages, chat.Message{ Role: chat.MessageRoleSystem, Content: a.Instruction() + "\n\n" + date, - CreatedAt: time.Now(), + CreatedAt: time.Now().Format(time.RFC3339), }) for _, tool := range a.ToolSets() { @@ -223,7 +223,7 @@ func (s *Session) GetMessages(a *agent.Agent) []chat.Message { messages = append(messages, chat.Message{ Role: chat.MessageRoleSystem, Content: tool.Instructions(), - CreatedAt: time.Now(), + CreatedAt: time.Now().Format(time.RFC3339), }) } } @@ -240,7 +240,7 @@ func (s *Session) GetMessages(a *agent.Agent) []chat.Message { messages = append(messages, chat.Message{ Role: chat.MessageRoleSystem, Content: "Session Summary: " + s.Messages[lastSummaryIndex].Summary, - CreatedAt: time.Now(), + CreatedAt: time.Now().Format(time.RFC3339), }) } From 745e2432ded7fc0fd1a0f9b66ddf612ca36a788c Mon Sep 17 00:00:00 2001 From: Trung Nguyen Date: Mon, 1 Sep 2025 17:58:23 +0700 Subject: [PATCH 3/3] Add createdAt for missing chat.Message Signed-off-by: Trung Nguyen --- pkg/runtime/runtime.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/runtime/runtime.go b/pkg/runtime/runtime.go index 02285ad39..bdf3e1477 100644 --- a/pkg/runtime/runtime.go +++ b/pkg/runtime/runtime.go @@ -603,6 +603,7 @@ func (r *Runtime) addToolRejectedResponse(sess *session.Session, toolCall tools. Role: chat.MessageRoleTool, Content: result, ToolCallID: toolCall.ID, + CreatedAt: time.Now().Format(time.RFC3339), } sess.AddMessage(session.NewAgentMessage(a, &toolResponseMsg)) }