diff --git a/packages/database/src/models/__tests__/task.test.ts b/packages/database/src/models/__tests__/task.test.ts index fbe9908a4f..850310a1b8 100644 --- a/packages/database/src/models/__tests__/task.test.ts +++ b/packages/database/src/models/__tests__/task.test.ts @@ -667,8 +667,18 @@ describe('TaskModel', () => { const model = new TaskModel(serverDB, userId); const task = await model.create({ instruction: 'Test' }); - await model.addComment({ content: 'First comment', taskId: task.id, userId }); - await model.addComment({ content: 'Second comment', taskId: task.id, userId }); + await model.addComment({ + authorUserId: userId, + content: 'First comment', + taskId: task.id, + userId, + }); + await model.addComment({ + authorUserId: userId, + content: 'Second comment', + taskId: task.id, + userId, + }); const comments = await model.getComments(task.id); expect(comments).toHaveLength(2); @@ -681,6 +691,7 @@ describe('TaskModel', () => { const task = await model.create({ instruction: 'Test' }); const comment = await model.addComment({ + authorUserId: userId, briefId: '00000000-0000-0000-0000-000000000001', content: 'Reply to brief', taskId: task.id, @@ -697,13 +708,14 @@ describe('TaskModel', () => { const task = await model.create({ instruction: 'Test' }); const comment = await model.addComment({ - agentId: 'agt_xxx', + authorAgentId: 'agt_xxx', content: 'Agent observation', taskId: task.id, + userId, }); - expect(comment.agentId).toBe('agt_xxx'); - expect(comment.userId).toBeNull(); + expect(comment.authorAgentId).toBe('agt_xxx'); + expect(comment.authorUserId).toBeNull(); }); it('should delete own comment', async () => { @@ -711,6 +723,7 @@ describe('TaskModel', () => { const task = await model.create({ instruction: 'Test' }); const comment = await model.addComment({ + authorUserId: userId, content: 'To be deleted', taskId: task.id, userId, @@ -729,6 +742,7 @@ describe('TaskModel', () => { const task = await model1.create({ instruction: 'Test' }); const comment = await model1.addComment({ + authorUserId: userId, content: 'User 1 comment', taskId: task.id, userId, @@ -742,9 +756,9 @@ describe('TaskModel', () => { const model = new TaskModel(serverDB, userId); const task = await model.create({ instruction: 'Test' }); - await model.addComment({ content: 'First', taskId: task.id, userId }); - await model.addComment({ content: 'Second', taskId: task.id, userId }); - await model.addComment({ content: 'Third', taskId: task.id, userId }); + await model.addComment({ authorUserId: userId, content: 'First', taskId: task.id, userId }); + await model.addComment({ authorUserId: userId, content: 'Second', taskId: task.id, userId }); + await model.addComment({ authorUserId: userId, content: 'Third', taskId: task.id, userId }); const comments = await model.getComments(task.id); expect(comments).toHaveLength(3); diff --git a/packages/database/src/models/__tests__/taskTopic.test.ts b/packages/database/src/models/__tests__/taskTopic.test.ts index 500513f773..8b334b25ab 100644 --- a/packages/database/src/models/__tests__/taskTopic.test.ts +++ b/packages/database/src/models/__tests__/taskTopic.test.ts @@ -102,10 +102,11 @@ describe('TaskTopicModel', () => { }); const topics = await topicModel.findByTaskId(task.id); - expect(topics[0].handoffTitle).toBe('第1章完成'); - expect(topics[0].handoffSummary).toBe('Completed chapter 1'); - expect(topics[0].handoffNextAction).toBe('Continue writing'); - expect(topics[0].handoffKeyFindings).toEqual(['Finding 1', 'Finding 2']); + const handoff = topics[0].handoff as any; + expect(handoff.title).toBe('第1章完成'); + expect(handoff.summary).toBe('Completed chapter 1'); + expect(handoff.nextAction).toBe('Continue writing'); + expect(handoff.keyFindings).toEqual(['Finding 1', 'Finding 2']); }); }); diff --git a/packages/database/src/models/taskTopic.ts b/packages/database/src/models/taskTopic.ts index ec9c34b159..a5fdcae8c3 100644 --- a/packages/database/src/models/taskTopic.ts +++ b/packages/database/src/models/taskTopic.ts @@ -1,3 +1,4 @@ +import type { TaskTopicHandoff } from '@lobechat/types'; import { and, desc, eq, sql } from 'drizzle-orm'; import type { TaskTopicItem } from '../schemas/task'; @@ -43,24 +44,10 @@ export class TaskTopicModel { ); } - async updateHandoff( - taskId: string, - topicId: string, - handoff: { - keyFindings?: string[]; - nextAction?: string; - summary?: string; - title?: string; - }, - ): Promise { + async updateHandoff(taskId: string, topicId: string, handoff: TaskTopicHandoff): Promise { await this.db .update(taskTopics) - .set({ - handoffKeyFindings: handoff.keyFindings, - handoffNextAction: handoff.nextAction, - handoffSummary: handoff.summary, - handoffTitle: handoff.title, - }) + .set({ handoff }) .where( and( eq(taskTopics.taskId, taskId), @@ -135,10 +122,7 @@ export class TaskTopicModel { return this.db .select({ createdAt: topics.createdAt, - handoffKeyFindings: taskTopics.handoffKeyFindings, - handoffNextAction: taskTopics.handoffNextAction, - handoffSummary: taskTopics.handoffSummary, - handoffTitle: taskTopics.handoffTitle, + handoff: taskTopics.handoff, id: topics.id, metadata: topics.metadata, operationId: taskTopics.operationId, @@ -162,10 +146,7 @@ export class TaskTopicModel { return this.db .select({ createdAt: taskTopics.createdAt, - handoffKeyFindings: taskTopics.handoffKeyFindings, - handoffNextAction: taskTopics.handoffNextAction, - handoffSummary: taskTopics.handoffSummary, - handoffTitle: taskTopics.handoffTitle, + handoff: taskTopics.handoff, seq: taskTopics.seq, status: taskTopics.status, topicId: taskTopics.topicId, diff --git a/packages/types/src/task/index.ts b/packages/types/src/task/index.ts index e6456cca2a..5e9bebc59a 100644 --- a/packages/types/src/task/index.ts +++ b/packages/types/src/task/index.ts @@ -31,6 +31,13 @@ export interface WorkspaceData { tree: WorkspaceTreeNode[]; } +export interface TaskTopicHandoff { + keyFindings?: string[]; + nextAction?: string; + summary?: string; + title?: string; +} + // ── Task Detail (shared across CLI, viewTask tool, task.detail router) ── export interface TaskDetailSubtask { diff --git a/src/server/routers/lambda/task.ts b/src/server/routers/lambda/task.ts index f7a531062c..453c9094a1 100644 --- a/src/server/routers/lambda/task.ts +++ b/src/server/routers/lambda/task.ts @@ -2,7 +2,7 @@ import { TaskIdentifier as TaskSkillIdentifier } from '@lobechat/builtin-skills' import { BriefIdentifier } from '@lobechat/builtin-tool-brief'; import { NotebookIdentifier } from '@lobechat/builtin-tool-notebook'; import { buildTaskRunPrompt } from '@lobechat/prompts'; -import type { WorkspaceData } from '@lobechat/types'; +import type { TaskTopicHandoff, WorkspaceData } from '@lobechat/types'; import { TRPCError } from '@trpc/server'; import { z } from 'zod'; @@ -175,7 +175,7 @@ async function buildTaskPrompt( type: b.type, })), comments: comments.map((c: any) => ({ - agentId: c.agentId, + agentId: c.authorAgentId, content: c.content, createdAt: c.createdAt, id: c.id, @@ -187,22 +187,17 @@ async function buildTaskPrompt( name: s.name, status: s.status, })), - topics: (topics as any[]).map((t) => ({ - createdAt: t.createdAt, - handoff: - t.handoffSummary || t.handoffTitle - ? { - keyFindings: t.handoffKeyFindings as string[] | undefined, - nextAction: t.handoffNextAction as string | undefined, - summary: t.handoffSummary as string | undefined, - title: t.handoffTitle as string | undefined, - } - : null, - id: t.topicId || t.id, - seq: t.seq, - status: t.status, - title: t.handoffTitle || t.title, - })), + topics: (topics as any[]).map((t) => { + const handoff = t.handoff as TaskTopicHandoff | null; + return { + createdAt: t.createdAt, + handoff, + id: t.topicId || t.id, + seq: t.seq, + status: t.status, + title: handoff?.title || t.title, + }; + }), }, extraPrompt, parentTask: parentTaskContext, @@ -325,6 +320,7 @@ export const taskRouter = router({ const model = ctx.taskModel; const task = await resolveOrThrow(model, input.id); const comment = await model.addComment({ + authorUserId: ctx.userId, briefId: input.briefId, content: input.content, taskId: task.id, diff --git a/src/server/services/task/index.ts b/src/server/services/task/index.ts index 8bf108402a..0b8fc0273f 100644 --- a/src/server/services/task/index.ts +++ b/src/server/services/task/index.ts @@ -2,6 +2,7 @@ import type { TaskDetailActivity, TaskDetailData, TaskDetailWorkspaceNode, + TaskTopicHandoff, WorkspaceData, } from '@lobechat/types'; @@ -92,7 +93,7 @@ export class TaskService { seq: t.seq, status: t.status, time: toISO(t.createdAt), - title: t.handoffTitle || 'Untitled', + title: (t.handoff as TaskTopicHandoff | null)?.title || 'Untitled', type: 'topic' as const, })), ...briefs.map((b) => ({ @@ -110,7 +111,7 @@ export class TaskService { type: 'brief' as const, })), ...comments.map((c) => ({ - agentId: c.agentId, + agentId: c.authorAgentId, content: c.content, time: toISO(c.createdAt), type: 'comment' as const,