feat: add agent activity feed functionality - #356
Conversation
- Introduced a new activity feed feature for agents, allowing users to view activities related to tasks and documents. - Added localization support for activity feed in Chinese (zh-CN). - Implemented backend logic for listing agent activities, including pagination and filtering options. - Created necessary database structures and indexes to support efficient querying of activity data. - Updated API endpoints to handle requests for agent activities, including validation and error handling. - Enhanced frontend components to display the activity feed within the agent detail view.
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
This PR adds the agent activity feed feature end-to-end: a new "Activity" tab on the agent detail page, a backend GET /projects/:projectId/agents/:agentId/activities endpoint, and supporting database indexes. The key changes:
- Frontend UI —
agent-activity-tab.tsx(infinite-scrolling feed, row links) andagent-activity-filters.tsx(search, source-type checkboxes, date-range popovers). - Data layer — new
AgentActivity*types,agentActivitiesQueryOptions, andlocalDateStartISO/localDateExclusiveEndISOdate conversion inagent-api.ts. - Cache invalidation —
use-project-realtime.tstargets theagentActivitiesquery-key prefix ontask.*/doc.*events. - Copy reuse —
activityDescriptionanddescribeDocActivityare exported and narrowed to the fields the new feed actually needs. - i18n — new
agents.detail.activity.*keys added to all eight locale files. - Backend API — cursor codec, domain/repository/service methods, DTO, handler validation, error mapping, and route wiring.
- Database — migration
000030replaces the single-columnidx_task_activities_actor_idwith partial composite indexes(actor_id, created_at DESC, id DESC).
ℹ️ Deployment note
000030 drops the old idx_task_activities_actor_id and creates a partial composite index on each activity table. The CREATE INDEX IF NOT EXISTS statements are idempotent, but on a very large task_activities/doc_activities table index creation can lock while it builds. Plan deploy sequencing accordingly for high-traffic tables.
Kimi K2 (free via Pullfrog for OSS) | 𝕏
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
This run covered the two commits since the last pullfrog review (3cbb6a38). The latest changes harden the activity feed around deleted sources and member/sprint name resolution:
- Deleted-source handling — added a
source_deletedboolean to the backendActivityFeedItem, repository CTE, response DTO, and frontendAgentActivitytype. The backend now computes(t|d).deleted_at IS NOT NULLin each UNION branch; the UI renders deleted task/document titles as plain text instead of links. - Member/sprint name resolution —
AgentActivityTabnow loadsprojectMembersQueryOptionsandsprintsQueryOptionsonce per project and passes a memoized{members, sprints}lookup map into the sharedactivityDescriptionhelper, so task activity copy shows names instead of truncated IDs. - Frontend tests — added
agent-activity-filters.test.tsx(search debounce, type toggle, clear-all) andagent-activity-tab.test.tsx(name resolution, fallback IDs, deleted source). - Backend tests — added
TestActivityFeedItemFromRecord_PreservesSourceDeletedand updated existing mapping assertions to cover the new field.
Kimi K2 (free via Pullfrog for OSS) | 𝕏

Summary
Adds an "Activity" tab to the agent detail page: a unified, cursor-paginated, filterable feed of every task and doc activity a given agent has performed across the project, styled like a log viewer with infinite scroll.
Backend
GET /projects/:projectId/agents/:agentId/activitiesendpoint (services/api/internal/transport/http/handler/agent_handler.go) resolves the agent'sproject_members.idviamemberRepo.FindMemberByAgent, then lists a keyset-paginated (created_at,id) page combiningtask_activitiesanddoc_activities, filterable bytype(task/doc),created_after/created_before, and free-textsearch(matches the linked task/doc title or activity content).AgentRepository.ListAgentActivities(services/api/internal/repository/postgres/agent_repository.go) implements this with a singleUNION ALLCTE over both tables joined totasks/documentsfor the display title, mirroring the existing conversations cursor-pagination pattern.domain/agent/activity_feed.goandcursor.go; newAgentActivityResponseDTO; newAGENT_ACTIVITY_INVALID_CURSORerror code.000030_add_activity_actor_cursor_indexes.sqladds composite(actor_id, created_at DESC, id DESC)indexes on both activity tables (doc_activitiespreviously had no actor index at all).Frontend
AgentActivityTab/AgentActivityFilterscomponents, modeled on the existing Conversations page'sIntersectionObserver-driven infinite scroll and filter popover.agentActivitiesQueryOptionscursor-paginated query inagent-api.ts, keyed separately from the"agents"prefix so realtime invalidation can target every agent's feed without over-invalidating other agent caches.activityDescription/describeDocActivityrenderers so the new tab reuses the same activity copy instead of duplicating it.task.*/doc.*realtime events to invalidate the activity feed.Test plan
go build ./...,go vet ./..., andgo test ./...inservices/api— new coverage for the query mapping, service passthrough, and every handler branch (missing member repo, wrong project, member not found, invalid type filter, success).golangci-lint run ./...inservices/api— clean.tsc -b,biome check ., andvitest runinapps/web— all clean (345 tests passing).