feat: make agent event include conversation entry

This commit is contained in:
2026-07-04 00:14:14 +01:00
parent 430a095f2a
commit 7eacbfd846
7 changed files with 655 additions and 85 deletions

View File

@@ -1,5 +1,3 @@
import type { AgentEvent } from "@freya/agent-protocol"
import { describe, expect, test } from "bun:test"
import type {
@@ -10,7 +8,11 @@ import type {
QueryAgentStreamEvent,
} from "./query-agent.ts"
import { streamAgentResponse } from "./streaming.ts"
import {
AgentResponseStreamEventKind,
streamAgentResponse,
type AgentResponseStreamEvent,
} from "./streaming.ts"
class FakeQueryAgent implements QueryAgent {
readonly inputs: QueryAgentAsk[] = []
@@ -54,11 +56,14 @@ describe("streamAgentResponse", () => {
)
expect(events).toEqual([
{ type: "conversation_started", conversationId: "conversation-1" },
{ type: "message_created", text: "First message" },
{ type: "message_created", text: "Second message" },
{ type: "message_created", text: "Third message" },
{ type: "message_finished" },
{
kind: AgentResponseStreamEventKind.ConversationStarted,
conversationId: "conversation-1",
},
{ kind: AgentResponseStreamEventKind.AssistantMessage, text: "First message" },
{ kind: AgentResponseStreamEventKind.AssistantMessage, text: "Second message" },
{ kind: AgentResponseStreamEventKind.AssistantMessage, text: "Third message" },
{ kind: AgentResponseStreamEventKind.ResponseFinished },
])
})
@@ -77,10 +82,13 @@ describe("streamAgentResponse", () => {
)
expect(events).toEqual([
{ type: "conversation_started", conversationId: "conversation-1" },
{ type: "message_created", text: " const value = 1 " },
{ type: "message_created", text: " return value" },
{ type: "message_finished" },
{
kind: AgentResponseStreamEventKind.ConversationStarted,
conversationId: "conversation-1",
},
{ kind: AgentResponseStreamEventKind.AssistantMessage, text: " const value = 1 " },
{ kind: AgentResponseStreamEventKind.AssistantMessage, text: " return value" },
{ kind: AgentResponseStreamEventKind.ResponseFinished },
])
})
@@ -97,25 +105,35 @@ describe("streamAgentResponse", () => {
agent,
input: { message: "hello" },
})
const events: AgentEvent[] = []
const events: AgentResponseStreamEvent[] = []
await expect(collectStreamAgentResponse(stream, events)).rejects.toThrow("model unavailable")
expect(events).toEqual([
{ type: "conversation_started", conversationId: "conversation-1" },
{ type: "message_created", text: "I'll check" },
{ type: "tool_started", toolName: "calendar" },
{ type: "tool_finished", toolName: "calendar", ok: false },
{ type: "message_created", text: "That failed" },
{ type: "message_failed", error: "model unavailable" },
{
kind: AgentResponseStreamEventKind.ConversationStarted,
conversationId: "conversation-1",
},
{ kind: AgentResponseStreamEventKind.AssistantMessage, text: "I'll check" },
{ kind: AgentResponseStreamEventKind.ToolStarted, toolName: "calendar" },
{
kind: AgentResponseStreamEventKind.ToolFinished,
toolName: "calendar",
ok: false,
},
{ kind: AgentResponseStreamEventKind.AssistantMessage, text: "That failed" },
{
kind: AgentResponseStreamEventKind.ResponseFailed,
error: "model unavailable",
},
])
})
})
async function collectStreamAgentResponse(
stream: AsyncIterable<AgentEvent>,
events: AgentEvent[] = [],
): Promise<AgentEvent[]> {
stream: AsyncIterable<AgentResponseStreamEvent>,
events: AgentResponseStreamEvent[] = [],
): Promise<AgentResponseStreamEvent[]> {
for await (const event of stream) {
events.push(event)
}