From d936ec29a8be1630ddeb6fe4137a4604f476d9e5 Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Fri, 7 Aug 2026 10:16:28 +0200 Subject: [PATCH] format: remove agent dependency from FormatEvent FormatEvent now takes primitive string arguments instead of agent.Event. This fixes the dependency direction - format/ should be a leaf package that agent/, session/, and fs/ depend on, not the other way around. --- format/event.go | 34 ++++++++++++++++------------------ fs/types.go | 24 ++++++++---------------- 2 files changed, 24 insertions(+), 34 deletions(-) diff --git a/format/event.go b/format/event.go index 303e413..8e88fa2 100644 --- a/format/event.go +++ b/format/event.go @@ -2,40 +2,38 @@ package format import ( "strings" - - "ollie/agent" ) -// FormatEvent converts an agent Event to bytes for appending to a chat log. -// Streaming roles (assistant, reasoning) return only the content chunk; +// FormatEvent converts event data to bytes for appending to a chat log. +// Streaming roles (assistant, reasoning, retry) return only the content chunk; // the caller is responsible for writing the [[[role]]] header for those. -func FormatEvent(ev agent.Event) []byte { - switch ev.Role { +func FormatEvent(role, name, content, outputFormat string) []byte { + switch role { case "user": - return []byte(UserTag + "\n" + ev.Content + "\n" + EndTag + "\n") + return []byte(UserTag + "\n" + content + "\n" + EndTag + "\n") case "assistant": - return []byte(ev.Content) + return []byte(content) case "reasoning": - return []byte(ev.Content) + return []byte(content) case "call": - args := strings.Join(strings.Fields(ev.Content), " ") - return []byte(CallDelim(ev.Name) + "```\n" + args + "\n```\n" + EndTag + "\n") + args := strings.Join(strings.Fields(content), " ") + return []byte(CallDelim(name) + "```\n" + args + "\n```\n" + EndTag + "\n") case "tool": fence := "```" - if ev.OutputFormat != "" { - fence += ev.OutputFormat + if outputFormat != "" { + fence += outputFormat } - return []byte(ToolDelim(ev.Name) + fence + "\n" + strings.TrimRight(ev.Content, "\n") + "\n```\n" + EndTag + "\n") + return []byte(ToolDelim(name) + fence + "\n" + strings.TrimRight(content, "\n") + "\n```\n" + EndTag + "\n") case "error": - return []byte(RoleDelim("error") + "\n" + ev.Content + "\n" + EndTag + "\n") + return []byte(RoleDelim("error") + "\n" + content + "\n" + EndTag + "\n") case "info": - return []byte(RoleDelim("info") + "\n" + ev.Content + "\n" + EndTag + "\n") + return []byte(RoleDelim("info") + "\n" + content + "\n" + EndTag + "\n") case "retry": - return []byte(ev.Content) + return []byte(content) case "stalled": return []byte(RoleDelim("stalled") + "\n" + EndTag + "\n") case "maxsteps": - return []byte(RoleDelim("maxsteps") + "\n" + ev.Content + "\n" + EndTag + "\n") + return []byte(RoleDelim("maxsteps") + "\n" + content + "\n" + EndTag + "\n") default: return nil } diff --git a/fs/types.go b/fs/types.go index 45fed7f..77893cf 100644 --- a/fs/types.go +++ b/fs/types.go @@ -211,7 +211,7 @@ func NewEventHandler(as *AgentLog) agent.EventHandler { } streamingRole = ev.Role } - as.AppendLog(format.FormatEvent(ev)) + as.AppendLog(format.FormatEvent(ev.Role, ev.Name, ev.Content, ev.OutputFormat)) case "reasoning": // Absorbed silently @@ -246,7 +246,7 @@ func NewEventHandler(as *AgentLog) agent.EventHandler { streamingFence = format.ToolFence streamingRole = "tool" } else { - as.AppendLog(format.FormatEvent(ev)) + as.AppendLog(format.FormatEvent(ev.Role, ev.Name, ev.Content, ev.OutputFormat)) } case "retry": @@ -260,7 +260,7 @@ func NewEventHandler(as *AgentLog) agent.EventHandler { } as.AppendLog([]byte(format.RetryTag + "\n")) streamingRole = "retry" - as.AppendLog(format.FormatEvent(ev)) + as.AppendLog(format.FormatEvent(ev.Role, ev.Name, ev.Content, ev.OutputFormat)) case "call": if streamingRole != "" { @@ -271,7 +271,7 @@ func NewEventHandler(as *AgentLog) agent.EventHandler { as.AppendLog([]byte("\n" + format.EndTag + "\n")) streamingRole = "" } - as.AppendLog(format.FormatEvent(ev)) + as.AppendLog(format.FormatEvent(ev.Role, ev.Name, ev.Content, ev.OutputFormat)) default: if streamingRole != "" { @@ -282,7 +282,7 @@ func NewEventHandler(as *AgentLog) agent.EventHandler { as.AppendLog([]byte("\n" + format.EndTag + "\n")) streamingRole = "" } - as.AppendLog(format.FormatEvent(ev)) + as.AppendLog(format.FormatEvent(ev.Role, ev.Name, ev.Content, ev.OutputFormat)) } } } @@ -315,7 +315,7 @@ func replayMessagesToLog(as *AgentLog, messages []backend.Message) { switch m.Role { case "system": case "user": - as.AppendLog(format.FormatEvent(agent.Event{Role: "user", Content: m.Content})) + as.AppendLog(format.FormatEvent("user", "", m.Content, "")) case "assistant": if m.ID != "" { as.AppendLog([]byte(format.AssistantHeaderPrefix + m.ID + "]]]\n")) @@ -327,22 +327,14 @@ func replayMessagesToLog(as *AgentLog, messages []backend.Message) { } as.AppendLog([]byte(format.EndTag + "\n")) for _, tc := range m.ToolCalls { - as.AppendLog(format.FormatEvent(agent.Event{ - Role: "call", - Name: tc.Name, - Content: string(tc.Arguments), - })) + as.AppendLog(format.FormatEvent("call", tc.Name, string(tc.Arguments), "")) } case "tool": name := callNames[m.ToolCallID] if name == "" { name = m.ToolCallID } - as.AppendLog(format.FormatEvent(agent.Event{ - Role: "tool", - Name: name, - Content: m.Content, - })) + as.AppendLog(format.FormatEvent("tool", name, m.Content, "")) } } }