feat(ssa): Implement dual-channel architecture Phase 1-3 (QPER + LLM Agent pipeline)

Completed:
- Phase 1: DB schema (execution_mode + ssa_agent_executions), ModeToggle component, Session PATCH API
- Phase 2: AgentPlannerService + AgentCoderService (streaming) + CodeRunnerService + R Docker /execute-code endpoint
- Phase 3: AgentCodePanel (3-step confirmation UI), SSE event handling (7 agent events), streaming code display
- Three-step confirmation pipeline: plan -> user confirm -> stream code -> user confirm -> execute R code -> results
- R Docker sandbox /execute-code endpoint with 120s timeout + block_helpers preloaded
- E2E dual-channel test script (8 tests)
- Updated R engine architecture doc (v1.5) and SSA module status doc (v4.0)

Technical details:
- AgentCoderService uses LLM streaming (chatStream) for real-time code generation feedback
- ReviewerAgent temporarily disabled, prioritizing Plan -> Code -> Execute flow
- CodeRunnerService wraps user code with auto data loading (df variable injection)
- Frontend handles agent_planning, agent_plan_ready, code_generating, code_generated, code_executing, code_result events
- ask_user mechanism used for plan and code confirmation steps

Files: 24 files (4 new services, 2 new components, 1 migration, 1 E2E test, 16 modified)
Made-with: Cursor
This commit is contained in:
2026-03-02 22:23:54 +08:00
parent 71d32d11ee
commit aadceb5cde
24 changed files with 2694 additions and 56 deletions

View File

@@ -0,0 +1,38 @@
-- AlterTable: ssa_sessions 新增 execution_mode 列
ALTER TABLE "ssa_schema"."ssa_sessions" ADD COLUMN IF NOT EXISTS "execution_mode" TEXT NOT NULL DEFAULT 'qper';
-- CreateTable: ssa_agent_executions (Agent 通道执行记录)
CREATE TABLE IF NOT EXISTS "ssa_schema"."ssa_agent_executions" (
"id" TEXT NOT NULL,
"session_id" TEXT NOT NULL,
"query" TEXT NOT NULL,
"plan_text" TEXT,
"generated_code" TEXT,
"review_result" JSONB,
"execution_result" JSONB,
"report_blocks" JSONB,
"retry_count" INTEGER NOT NULL DEFAULT 0,
"status" TEXT NOT NULL DEFAULT 'pending',
"error_message" TEXT,
"duration_ms" INTEGER,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "ssa_agent_executions_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX IF NOT EXISTS "idx_ssa_agent_exec_session" ON "ssa_schema"."ssa_agent_executions"("session_id");
-- AddForeignKey
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'ssa_agent_executions_session_id_fkey'
) THEN
ALTER TABLE "ssa_schema"."ssa_agent_executions"
ADD CONSTRAINT "ssa_agent_executions_session_id_fkey"
FOREIGN KEY ("session_id") REFERENCES "ssa_schema"."ssa_sessions"("id")
ON DELETE CASCADE ON UPDATE CASCADE;
END IF;
END $$;