Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/session-comments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@electric-ax/agents-runtime": patch
"@electric-ax/agents-server": patch
"@electric-ax/agents-server-ui": patch
---

Add session comments to agent timelines, including synced comment events, server comment writes, reply targets, comments-only timeline display, and timeline controls for showing or hiding comments.
5 changes: 5 additions & 0 deletions packages/agents-runtime/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export {
compareTimelineOrders,
buildEntityTimelineData,
createPendingTimelineOrder,
TIMELINE_ORDER_FALLBACK,
createEntityErrorsQuery,
createEntityIncludesQuery,
createEntityTimelineQuery,
Expand Down Expand Up @@ -44,6 +45,9 @@ export type {
AttachmentStatus,
AttachmentSubject,
AttachmentSubjectType,
Comment,
CommentSnapshot,
CommentTarget,
Manifest,
ManifestAttachmentEntry,
} from './entity-schema'
Expand All @@ -64,6 +68,7 @@ export type {
export type {
EntityTimelineContentItem,
EntityTimelineData,
EntityTimelineCommentRow,
EntityTimelineInboxMode,
EntityTimelineQueryOptions,
EntityTimelineQueryRow,
Expand Down
96 changes: 96 additions & 0 deletions packages/agents-runtime/src/entity-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,43 @@ type MessageReceivedValue = {
processed_at?: string
cancelled_at?: string
}
type CommentTargetCollectionValue =
| `inbox`
| `run`
| `text`
| `tool_call`
| `wake`
| `signal`
| `manifest`
type CommentTargetValue =
| {
kind: `comment`
key: string
}
| {
kind: `timeline`
collection: CommentTargetCollectionValue
key: string
run_id?: string
}
type CommentSnapshotValue = {
label: string
text?: string
from?: string
timestamp?: string
collection?: string
}
type CommentValue = {
key?: string
body: string
from_principal: string
timestamp: string
reply_to?: CommentTargetValue
target_snapshot?: CommentSnapshotValue
edited_at?: string
deleted_at?: string
deleted_by?: string
}
type WakeEntryValue = {
key?: string
timestamp: string
Expand Down Expand Up @@ -552,6 +589,54 @@ function createMessageReceivedSchema(): Schema<MessageReceivedValue> {
})
}

function createCommentTargetSchema(): Schema<CommentTargetValue> {
return z.union([
z.object({
kind: z.literal(`comment`),
key: z.string(),
}),
z.object({
kind: z.literal(`timeline`),
collection: z.enum([
`inbox`,
`run`,
`text`,
`tool_call`,
`wake`,
`signal`,
`manifest`,
]),
key: z.string(),
run_id: z.string().optional(),
}),
])
}

function createCommentSnapshotSchema(): Schema<CommentSnapshotValue> {
return z.object({
label: z.string(),
text: z.string().optional(),
from: z.string().optional(),
timestamp: z.string().optional(),
collection: z.string().optional(),
})
}

function createCommentSchema(): Schema<CommentValue> {
return z.object({
key: z.string().optional(),
...timelineOrderField,
body: z.string(),
from_principal: z.string(),
timestamp: z.string(),
reply_to: createCommentTargetSchema().optional(),
target_snapshot: createCommentSnapshotSchema().optional(),
edited_at: z.string().optional(),
deleted_at: z.string().optional(),
deleted_by: z.string().optional(),
})
}

function createWakeSchema(): Schema<WakeEntryValue> {
return z.object({
key: z.string().optional(),
Expand Down Expand Up @@ -851,6 +936,9 @@ export type ToolCall = SequencedPersistedRow<ToolCallValue>
export type Reasoning = SequencedPersistedRow<ReasoningValue>
export type ErrorEvent = SequencedPersistedRow<ErrorEventValue>
export type MessageReceived = SequencedPersistedRow<MessageReceivedValue>
export type CommentTarget = CommentTargetValue
export type CommentSnapshot = CommentSnapshotValue
export type Comment = SequencedPersistedRow<CommentValue>
export type WakeEntry = SequencedPersistedRow<WakeEntryValue>
export type EntityCreated = SequencedPersistedRow<EntityCreatedValue>
export type EntityStopped = SequencedPersistedRow<EntityStoppedValue>
Expand Down Expand Up @@ -941,6 +1029,7 @@ export const ENTITY_COLLECTIONS = {
reasoning: `reasoning`,
errors: `errors`,
inbox: `inbox`,
comments: `comments`,
wakes: `wakes`,
entityCreated: `entityCreated`,
entityStopped: `entityStopped`,
Expand All @@ -966,6 +1055,7 @@ export const BUILT_IN_EVENT_SCHEMAS = {
error: createErrorEventSchema() as unknown as BuiltInEntitySchema<ErrorEvent>,
inbox:
createMessageReceivedSchema() as unknown as BuiltInEntitySchema<MessageReceived>,
comment: createCommentSchema() as unknown as BuiltInEntitySchema<Comment>,
wake: createWakeSchema() as unknown as BuiltInEntitySchema<WakeEntry>,
entity_created:
createEntityCreatedSchema() as unknown as BuiltInEntitySchema<EntityCreated>,
Expand Down Expand Up @@ -1000,6 +1090,7 @@ type EntityCollectionsDefinition = {
reasoning: CollectionDefinition<Reasoning>
errors: CollectionDefinition<ErrorEvent>
inbox: CollectionDefinition<MessageReceived>
comments: CollectionDefinition<Comment>
wakes: CollectionDefinition<WakeEntry>
entityCreated: CollectionDefinition<EntityCreated>
entityStopped: CollectionDefinition<EntityStopped>
Expand Down Expand Up @@ -1060,6 +1151,11 @@ export const builtInCollections: EntityCollectionsDefinition = {
type: `inbox`,
primaryKey: `key`,
},
comments: {
schema: BUILT_IN_EVENT_SCHEMAS.comment as StandardSchemaV1<Comment>,
type: `comment`,
primaryKey: `key`,
},
wakes: {
schema: BUILT_IN_EVENT_SCHEMAS.wake as StandardSchemaV1<WakeEntry>,
type: `wake`,
Expand Down
Loading
Loading