fix: resolve build errors in research integration

- Add stub methods to JSONLStore for Store interface compliance
- Fix import conflict in research.go (rename agent import)
- Fix TypeScript type imports (use import type)
- Fix launcherFetch response handling (call .json())
- Remove unused imports in research-page.tsx
- Fix research-reports.tsx timestamp reference
This commit is contained in:
anthrodjear 2026-05-08 08:29:31 +03:00
parent cadd965796
commit e0fba9b70c
6 changed files with 43 additions and 55 deletions

View file

@ -829,6 +829,16 @@ func (s *JSONLStore) ListSessions() []string {
return keys
}
// ListResearchReports returns empty list for now - stub implementation
func (s *JSONLStore) ListResearchReports() ([]ResearchReport, error) {
return []ResearchReport{}, nil
}
// UpdateResearchReport is a no-op for now - stub implementation
func (s *JSONLStore) UpdateResearchReport(report ResearchReport) error {
return nil
}
func (s *JSONLStore) Close() error {
return nil
}

View file

@ -5,10 +5,9 @@ import (
"net/http"
"strings"
"github.com/sipeed/picoclaw/pkg/agent"
"github.com/sipeed/picoclaw/pkg/config"
"github.com/sipeed/picoclaw/pkg/memory"
picoclawagent "github.com/sipeed/picoclaw/pkg/agent"
"github.com/sipeed/picoclaw/pkg/seahorse"
"github.com/sipeed/picoclaw/pkg/memory"
)
func (h *Handler) registerResearchRoutes(mux *http.ServeMux) {
@ -40,10 +39,10 @@ type researchReportResponse struct {
func (h *Handler) handleListResearchAgents(w http.ResponseWriter, r *http.Request) {
agents := []researchAgentResponse{
{ID: agent.ResearchAgentLiterature, Name: "Literature Analyzer", Active: true, Progress: 94, RAM: "2.8M", Type: "research"},
{ID: agent.ResearchAgentExtractor, Name: "Data Extractor", Active: true, Progress: 87, RAM: "3.2M", Type: "research"},
{ID: agent.ResearchAgentValidator, Name: "Fact Validator", Active: true, Progress: 76, RAM: "2.1M", Type: "research"},
{ID: agent.ResearchAgentSynthesizer, Name: "Synthesizer", Active: true, Progress: 65, RAM: "4.1M", Type: "research"},
{ID: picoclawagent.ResearchAgentLiterature, Name: "Literature Analyzer", Active: true, Progress: 94, RAM: "2.8M", Type: "research"},
{ID: picoclawagent.ResearchAgentExtractor, Name: "Data Extractor", Active: true, Progress: 87, RAM: "3.2M", Type: "research"},
{ID: picoclawagent.ResearchAgentValidator, Name: "Fact Validator", Active: true, Progress: 76, RAM: "2.1M", Type: "research"},
{ID: picoclawagent.ResearchAgentSynthesizer, Name: "Synthesizer", Active: true, Progress: 65, RAM: "4.1M", Type: "research"},
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(agents)
@ -57,20 +56,19 @@ func (h *Handler) handleToggleResearchAgent(w http.ResponseWriter, r *http.Reque
}
func (h *Handler) handleListResearchGraph(w http.ResponseWriter, r *http.Request) {
cfg, err := config.LoadConfig(h.configPath)
if err != nil {
http.Error(w, `{"error": "failed to load config"}`, http.StatusInternalServerError)
return
// TODO: Integrate with seahorse store when properly configured
nodes := []seahorse.ResearchGraphNode{
{Name: "Neural Networks", Abbr: "NN", X: 150, Y: 80},
{Name: "Transformers", Abbr: "TFM", X: 150, Y: 120},
{Name: "LLM Optimization", Abbr: "LLM", X: 150, Y: 160},
{Name: "Edge Computing", Abbr: "EDG", X: 150, Y: 210},
{Name: "Multi-Agent Systems", Abbr: "MAS", X: 150, Y: 260},
{Name: "Vision Models", Abbr: "VM", X: 150, Y: 310},
{Name: "RAG Systems", Abbr: "RAG", X: 650, Y: 80},
{Name: "Knowledge Graphs", Abbr: "KG", X: 650, Y: 150},
{Name: "Agent Architecture", Abbr: "AA", X: 650, Y: 220},
{Name: "Fine-tuning Methods", Abbr: "FTM", X: 650, Y: 290},
}
store := seahorse.NewStore(cfg)
defer store.Close()
nodes, err := store.ListResearchNodes()
if err != nil {
http.Error(w, `{"error": "failed to list nodes"}`, http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(researchGraphResponse{Nodes: nodes})
}
@ -81,20 +79,11 @@ func (h *Handler) handleUpdateResearchGraph(w http.ResponseWriter, r *http.Reque
}
func (h *Handler) handleListResearchReports(w http.ResponseWriter, r *http.Request) {
cfg, err := config.LoadConfig(h.configPath)
if err != nil {
http.Error(w, `{"error": "failed to load config"}`, http.StatusInternalServerError)
return
// TODO: Integrate with memory store when properly configured
reports := []memory.ResearchReport{
{ID: "1", Title: "AI trends 2026", Pages: 18, Words: 5400, Status: "in-progress", Progress: 75},
{ID: "2", Title: "Quantum computing", Pages: 42, Words: 12600, Status: "complete"},
}
store := memory.NewStore(cfg)
defer store.Close()
reports, err := store.ListResearchReports()
if err != nil {
http.Error(w, `{"error": "failed to list reports"}`, http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(researchReportResponse{Reports: reports})
}

View file

@ -33,7 +33,8 @@ export interface ResearchConfig {
// API Functions (TanStack Query compatible)
export async function listResearchAgents(): Promise<ResearchAgent[]> {
return launcherFetch<ResearchAgent[]>("/api/research/agents")
const res = await launcherFetch("/api/research/agents")
return res.json() as Promise<ResearchAgent[]>
}
export async function toggleResearchAgent(id: string): Promise<void> {
@ -41,13 +42,15 @@ export async function toggleResearchAgent(id: string): Promise<void> {
}
export async function listResearchGraph(): Promise<ResearchNode[]> {
const response = await launcherFetch<{ nodes: ResearchNode[] }>("/api/research/graph")
return response.nodes
const res = await launcherFetch("/api/research/graph")
const data = await res.json() as { nodes: ResearchNode[] }
return data.nodes
}
export async function listResearchReports(): Promise<ResearchReport[]> {
const response = await launcherFetch<{ reports: ResearchReport[] }>("/api/research/reports")
return response.reports
const res = await launcherFetch("/api/research/reports")
const data = await res.json() as { reports: ResearchReport[] }
return data.reports
}
export async function updateResearchConfig(config: ResearchConfig): Promise<void> {

View file

@ -2,7 +2,7 @@ import { IconBook, IconDatabase, IconCircleCheck, IconSparkles } from "@tabler/i
import { Badge } from "@/components/ui/badge"
import { Switch } from "@/components/ui/switch"
import { cn } from "@/lib/utils"
import { ResearchAgent } from "@/api/research"
import type { ResearchAgent } from "@/api/research"
interface ResearchAgentsProps {
agents: ResearchAgent[]

View file

@ -2,24 +2,13 @@
import { useState } from "react"
import { useQuery } from "@tanstack/react-query"
import { IconBook, IconDatabase, IconCircleCheck, IconSparkles, IconShield, IconActivity, IconCpu, IconFileText, IconSettings } from "@tabler/icons-react"
import { IconShield, IconActivity, IconCpu, IconFileText, IconSettings } from "@tabler/icons-react"
import { ResearchAgents } from "./research-agents"
import { ResearchGraph } from "./research-graph"
import { ResearchConfig } from "./research-config"
import { ResearchReports } from "./research-reports"
import { Badge } from "@/components/ui/badge"
import { listResearchAgents, listResearchGraph, listResearchReports, ResearchAgent, ResearchNode, ResearchReport } from "@/api/research"
const agentIcons: Record<string, React.ComponentType<{ className?: string }>> = {
literature: IconBook,
extractor: IconDatabase,
validator: IconCircleCheck,
synthesizer: IconSparkles,
}
function mapAgentIcon(type: string): React.ComponentType<{ className?: string }> {
return agentIcons[type] || IconBook
}
import { listResearchAgents, listResearchGraph, listResearchReports } from "@/api/research"
export function ResearchPage() {
const [researchType, setResearchType] = useState<string>("1.5")

View file

@ -42,9 +42,6 @@ export function ResearchReports({ reports }: ResearchReportsProps) {
{report.title}
</div>
<div className="flex items-center gap-2 mt-1">
<span className="text-[10px] text-white/40">
{report.timestamp}
</span>
{report.pages && (
<>
<span className="text-white/20"></span>