mirror of
https://github.com/kennethnym/freya
synced 2026-07-05 07:21:15 +01:00
feat: add agent protocol entry events (#157)
* feat: add agent protocol events * feat: add tool payload schemas
This commit is contained in:
3
bun.lock
3
bun.lock
@@ -158,6 +158,9 @@
|
|||||||
"packages/freya-agent-protocol": {
|
"packages/freya-agent-protocol": {
|
||||||
"name": "@freya/agent-protocol",
|
"name": "@freya/agent-protocol",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@freya/core": "workspace:*",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"packages/freya-components": {
|
"packages/freya-components": {
|
||||||
"name": "@freya/components",
|
"name": "@freya/components",
|
||||||
|
|||||||
@@ -6,5 +6,8 @@
|
|||||||
"types": "src/index.ts",
|
"types": "src/index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "bun test ./src"
|
"test": "bun test ./src"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@freya/core": "workspace:*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,40 @@
|
|||||||
|
import { ConversationEntryKind, ConversationEntryVisibility } from "@freya/core"
|
||||||
import { describe, expect, test } from "bun:test"
|
import { describe, expect, test } from "bun:test"
|
||||||
|
|
||||||
import type { AgentEvent, AgentServerApi } from "./index"
|
import { AgentEventKind, type AgentEvent, type AgentServerApi } from "./index"
|
||||||
|
|
||||||
describe("agent protocol", () => {
|
describe("agent protocol", () => {
|
||||||
test("defines server methods and agent events", () => {
|
test("defines server methods and agent events", () => {
|
||||||
const server: AgentServerApi = {
|
const server: AgentServerApi = {
|
||||||
async sendMessage(message) {
|
async sendMessage(message) {
|
||||||
return { message, conversationId: "conversation-1" }
|
return {
|
||||||
|
id: "entry-1",
|
||||||
|
conversationId: "conversation-1",
|
||||||
|
sequence: 1,
|
||||||
|
kind: ConversationEntryKind.UserMessage,
|
||||||
|
visibility: ConversationEntryVisibility.UserVisible,
|
||||||
|
fileId: null,
|
||||||
|
payload: {
|
||||||
|
role: "user",
|
||||||
|
parts: [{ type: "text", text: message }],
|
||||||
|
},
|
||||||
|
metadata: {},
|
||||||
|
createdAt: "2026-07-03T00:00:00.000Z",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
notify() {
|
||||||
|
// no-op for protocol shape test
|
||||||
},
|
},
|
||||||
ping() {
|
ping() {
|
||||||
return "pong"
|
return "pong"
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
const event: AgentEvent = { type: "message_finished" }
|
const event: AgentEvent = {
|
||||||
|
kind: AgentEventKind.ResponseFinished,
|
||||||
|
conversationId: "conversation-1",
|
||||||
|
}
|
||||||
|
|
||||||
expect(server.ping()).toBe("pong")
|
expect(server.ping()).toBe("pong")
|
||||||
expect(event.type).toBe("message_finished")
|
expect(event.kind).toBe(AgentEventKind.ResponseFinished)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,18 +1,46 @@
|
|||||||
export interface SendMessageResult {
|
import type { ConversationEntry } from "@freya/core"
|
||||||
message: string
|
|
||||||
|
export const AgentEventKind = {
|
||||||
|
ConversationStarted: "conversation_started",
|
||||||
|
ConversationEntryCreated: "conversation_entry_created",
|
||||||
|
ResponseFinished: "response_finished",
|
||||||
|
ResponseFailed: "response_failed",
|
||||||
|
} as const
|
||||||
|
|
||||||
|
export type AgentEventKind = (typeof AgentEventKind)[keyof typeof AgentEventKind]
|
||||||
|
|
||||||
|
export interface AgentConversationStartedEvent {
|
||||||
|
kind: typeof AgentEventKind.ConversationStarted
|
||||||
conversationId: string
|
conversationId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AgentConversationEntryCreatedEvent {
|
||||||
|
kind: typeof AgentEventKind.ConversationEntryCreated
|
||||||
|
entry: ConversationEntry
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AgentResponseFinishedEvent {
|
||||||
|
kind: typeof AgentEventKind.ResponseFinished
|
||||||
|
conversationId: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AgentResponseFailedEvent {
|
||||||
|
kind: typeof AgentEventKind.ResponseFailed
|
||||||
|
conversationId: string
|
||||||
|
error: string
|
||||||
|
}
|
||||||
|
|
||||||
export type AgentEvent =
|
export type AgentEvent =
|
||||||
| { type: "conversation_started"; conversationId: string }
|
| AgentConversationStartedEvent
|
||||||
| { type: "message_created"; text: string }
|
| AgentConversationEntryCreatedEvent
|
||||||
| { type: "tool_started"; toolName: string }
|
| AgentResponseFinishedEvent
|
||||||
| { type: "tool_finished"; toolName: string; ok: boolean }
|
| AgentResponseFailedEvent
|
||||||
| { type: "message_finished" }
|
|
||||||
| { type: "message_failed"; error: string }
|
export type UserEvent = { type: "typing" }
|
||||||
|
|
||||||
export interface AgentServerApi {
|
export interface AgentServerApi {
|
||||||
sendMessage(message: string): Promise<SendMessageResult>
|
sendMessage(message: string): Promise<ConversationEntry>
|
||||||
|
notify(event: UserEvent): void
|
||||||
ping(): "pong"
|
ping(): "pong"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -146,6 +146,19 @@ export const ConversationEntryMetadata = type({
|
|||||||
/** Metadata bag attached to a conversation entry. */
|
/** Metadata bag attached to a conversation entry. */
|
||||||
export type ConversationEntryMetadata = typeof ConversationEntryMetadata.infer
|
export type ConversationEntryMetadata = typeof ConversationEntryMetadata.infer
|
||||||
|
|
||||||
|
export const ToolCallPayload = type({
|
||||||
|
toolName: "string",
|
||||||
|
})
|
||||||
|
|
||||||
|
export type ToolCallPayload = typeof ToolCallPayload.infer
|
||||||
|
|
||||||
|
export const ToolResultPayload = type({
|
||||||
|
toolName: "string",
|
||||||
|
ok: "boolean",
|
||||||
|
})
|
||||||
|
|
||||||
|
export type ToolResultPayload = typeof ToolResultPayload.infer
|
||||||
|
|
||||||
/** Generic object payload used by operational entries. */
|
/** Generic object payload used by operational entries. */
|
||||||
export const GenericObjectPayload = type("Record<string, unknown>")
|
export const GenericObjectPayload = type("Record<string, unknown>")
|
||||||
|
|
||||||
@@ -158,6 +171,8 @@ export type ConversationEntryPayload =
|
|||||||
| AssistantMessagePayload
|
| AssistantMessagePayload
|
||||||
| AttachmentPayload
|
| AttachmentPayload
|
||||||
| ContextSummaryPayload
|
| ContextSummaryPayload
|
||||||
|
| ToolCallPayload
|
||||||
|
| ToolResultPayload
|
||||||
| GenericObjectPayload
|
| GenericObjectPayload
|
||||||
|
|
||||||
export const Conversation = type({
|
export const Conversation = type({
|
||||||
|
|||||||
@@ -29,7 +29,9 @@ export {
|
|||||||
SystemNoteConversationEntry,
|
SystemNoteConversationEntry,
|
||||||
TextMessagePart,
|
TextMessagePart,
|
||||||
ToolCallConversationEntry,
|
ToolCallConversationEntry,
|
||||||
|
ToolCallPayload,
|
||||||
ToolResultConversationEntry,
|
ToolResultConversationEntry,
|
||||||
|
ToolResultPayload,
|
||||||
UserMessagePayload,
|
UserMessagePayload,
|
||||||
UserMessageConversationEntry,
|
UserMessageConversationEntry,
|
||||||
} from "./conversation"
|
} from "./conversation"
|
||||||
|
|||||||
Reference in New Issue
Block a user