File size: 3,581 Bytes
e92be04
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { db } from "../config/gun.js";
import { broadcastHiveEvent } from "./hiveService.js";
import { updateAgentPresence } from "./agentService.js";
import { gunSafe } from "../utils/gunUtils.js";

// ── Shared Logic ──────────────────────────────────────────────
export function fetchHiveState() {
    return new Promise((resolve) => {
        const agents = [];
        const papers = [];
        let settled = false;

        const finish = () => {
             if (settled) return;
             settled = true;
             // Sort papers by recency (if possible) or just reverse
             resolve({ 
                 agents: agents.slice(0, 10), 
                 papers: papers.slice(0, 10).reverse() 
             });
        };

        // Listen for data
        const cutoff = Date.now() - 2 * 60 * 1000; // 2 minutes TTL
        db.get("agents").map().once((data, id) => {
            if (data && data.lastSeen && data.lastSeen > cutoff) {
                agents.push({ name: data.name || id, role: data.role || 'researcher' });
            }
        });
        
        db.get("p2pclaw_papers_v4").map().once((data, id) => {
            if (data && data.title) {
                papers.push({ 
                    title: data.title, 
                    abstract: data.content ? data.content.substring(0, 150) + "..." : "No abstract",
                    ipfs_link: data.url_html || null
                });
            }
        });

        // Hard deadline: resolve after 2s no matter what (Gun can be slow to 'finish')
        setTimeout(finish, 2000);
    });
}

// Update investigation progress based on paper content
export function updateInvestigationProgress(paperTitle, paperContent) {
  const keywords = (paperTitle + " " + paperContent).toLowerCase();
  
  // Define active investigations (could be dynamic in future)
  const investigations = [
    { id: "inv-001", match: ["melanoma", "skin", "cancer", "dermatology"] },
    { id: "inv-002", match: ["liver", "fibrosis", "hepatology", "hepatic"] },
    { id: "inv-003", match: ["chimera", "neural", "architecture", "topology"] },
  ];

  investigations.forEach(inv => {
    const hits = inv.match.filter(kw => keywords.includes(kw)).length;
    if (hits >= 1) { // Threshold: at least 1 keyword match
      db.get("investigations").get(inv.id).once(data => {
        const currentProgress = (data && data.progress) || 0;
        // Increment progress (cap at 100)
        // Logic: specific papers add 5-10% progress
        const increment = 10; 
        const newProgress = Math.min(100, currentProgress + increment);
        
        db.get("investigations").get(inv.id).put(gunSafe({ progress: newProgress }));
        console.log(`[SCIENCE] Investigation ${inv.id} progress updated to ${newProgress}%`);
      });
    }
  });
}

export async function sendToHiveChat(sender, text) {
    const msgId = `msg-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
    
    // Role-based logic: Check if it's a TASK
    let type = 'text';
    if (text.startsWith('TASK:')) {
        type = 'task';
    }

    db.get("chat").get(msgId).put(gunSafe({
        sender: sender,
        text: text,
        type: type,
        timestamp: Date.now()
    }));
}