feat(FN-1259): add review handoff mechanism for user assignment

- Add assigneeUserId field to Task type and SQLite schema for human assignment
- Add reviewHandoffPolicy setting to control automatic handoff behavior
- Implement handoff detection in executor: detect user assignment during review and auto-transition task
- Add dashboard API routes for user assignment, handoff queries, and completion
- Add frontend API functions: getHandoffTask, assignTaskToUser, completeHandoff
- Add comprehensive tests for store methods, API routes, and executor handoff logic
- Update memory documentation with review handoff pattern
This commit is contained in:
gsxdsm
2026-04-09 21:06:19 -07:00
parent cc4382835d
commit e404444439
16 changed files with 476 additions and 19 deletions

View File

@@ -1,5 +1,6 @@
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { AgentSemaphore } from "./concurrency.js";
import { detectReviewHandoffIntent } from "./executor.js";
// Mock external dependencies
vi.mock("./pi.js", () => ({
@@ -9147,3 +9148,48 @@ describe("StepSessionExecutor integration", () => {
expect(() => ctorOptions.onStepComplete!(0, { stepIndex: 0, success: true, retries: 0 })).not.toThrow();
});
});
describe("detectReviewHandoffIntent", () => {
it("returns true for 'send it back to me'", () => {
expect(detectReviewHandoffIntent("Please send it back to me for review")).toBe(true);
});
it("returns true for 'hand off to user'", () => {
expect(detectReviewHandoffIntent("I need to hand off to user")).toBe(true);
});
it("returns true for 'needs human review'", () => {
expect(detectReviewHandoffIntent("This needs human review")).toBe(true);
});
it("returns true for 'assign to user'", () => {
expect(detectReviewHandoffIntent("Please assign to user")).toBe(true);
});
it("returns true for 'return to user'", () => {
expect(detectReviewHandoffIntent("Return to user for final approval")).toBe(true);
});
it("returns true for 'user review needed'", () => {
expect(detectReviewHandoffIntent("User review needed")).toBe(true);
});
it("returns true for 'requesting user review'", () => {
expect(detectReviewHandoffIntent("I am requesting user review")).toBe(true);
});
it("is case-insensitive", () => {
expect(detectReviewHandoffIntent("SEND IT BACK TO ME")).toBe(true);
expect(detectReviewHandoffIntent("Send It Back To Me")).toBe(true);
});
it("returns false for regular comments without handoff intent", () => {
expect(detectReviewHandoffIntent("Good progress on the implementation")).toBe(false);
expect(detectReviewHandoffIntent("Please add more tests")).toBe(false);
expect(detectReviewHandoffIntent("The code looks great")).toBe(false);
});
it("returns false for empty strings", () => {
expect(detectReviewHandoffIntent("")).toBe(false);
});
});