Compare commits

...

10 Commits

4 changed files with 168 additions and 0 deletions

96
app.js
View File

@@ -500,6 +500,95 @@ class AdaptiveCalibrator {
}
}
// ═══ NOSTR AGENT REGISTRATION ═══
class NostrAgent {
constructor(pubkey) {
this.pubkey = pubkey;
this.relays = ['wss://relay.damus.io', 'wss://nos.lol'];
}
async announce(metadata) {
console.log(`[NOSTR] Announcing agent ${this.pubkey}...`);
const event = {
kind: 0,
pubkey: this.pubkey,
created_at: Math.floor(Date.now() / 1000),
tags: [],
content: JSON.stringify(metadata),
id: 'mock_id',
sig: 'mock_sig'
};
this.relays.forEach(url => {
console.log(`[NOSTR] Publishing to ${url}: `, event);
});
const container = document.getElementById('nostr-log-content');
if (container) {
const div = document.createElement('div');
div.className = 'nostr-entry';
div.innerHTML = `<span class="nostr-pubkey">[${this.pubkey.substring(0,8)}...]</span> <span class="nostr-status">ANNOUNCED</span>`;
container.prepend(div);
}
}
}
// ═══ L402 CLIENT LOGIC ═══
class L402Client {
async fetchWithL402(url) {
console.log(`[L402] Fetching ${url}...`);
const response = await fetch(url);
if (response.status === 402) {
const authHeader = response.headers.get('WWW-Authenticate');
console.log(`[L402] Challenge received: ${authHeader}`);
const container = document.getElementById('l402-log-content');
if (container) {
const div = document.createElement('div');
div.className = 'l402-entry';
div.innerHTML = `<span class="l402-status">CHALLENGE</span> <span class="l402-msg">Payment Required</span>`;
container.prepend(div);
}
return { status: 402, challenge: authHeader };
}
return response.json();
}
}
let nostrAgent, l402Client;
// ═══ PARALLEL SYMBOLIC EXECUTION (PSE) ═══
class PSELayer {
constructor() {
this.worker = new Worker('gofai_worker.js');
this.worker.onmessage = (e) => this.handleWorkerMessage(e);
this.pendingRequests = new Map();
}
handleWorkerMessage(e) {
const { type, results, plan } = e.data;
if (type === 'REASON_RESULT') {
results.forEach(res => symbolicEngine.logReasoning(res.rule, res.outcome));
} else if (type === 'PLAN_RESULT') {
symbolicPlanner.logPlan(plan);
}
}
offloadReasoning(facts, rules) {
this.worker.postMessage({ type: 'REASON', data: { facts, rules } });
}
offloadPlanning(initialState, goalState, actions) {
this.worker.postMessage({ type: 'PLAN', data: { initialState, goalState, actions } });
}
}
let pseLayer;
let metaLayer, neuroBridge, cbr, symbolicPlanner, knowledgeGraph, blackboard, symbolicEngine, calibrator;
let agentFSMs = {};
@@ -511,6 +600,10 @@ function setupGOFAI() {
cbr = new CaseBasedReasoner();
neuroBridge = new NeuroSymbolicBridge(symbolicEngine, blackboard);
metaLayer = new MetaReasoningLayer(symbolicPlanner, blackboard);
nostrAgent = new NostrAgent("npub1...");
l402Client = new L402Client();
nostrAgent.announce({ name: "Timmy Nexus Agent", capabilities: ["GOFAI", "L402"] });
pseLayer = new PSELayer();
calibrator = new AdaptiveCalibrator('nexus-v1', { base_rate: 0.05 });
// Setup initial facts
@@ -534,10 +627,13 @@ function updateGOFAI(delta, elapsed) {
// Run reasoning
if (Math.floor(elapsed * 2) > Math.floor((elapsed - delta) * 2)) {
symbolicEngine.reason();
pseLayer.offloadReasoning(Array.from(symbolicEngine.facts.entries()), symbolicEngine.rules.map(r => ({ description: r.description })));
document.getElementById("pse-task-count").innerText = parseInt(document.getElementById("pse-task-count").innerText) + 1;
metaLayer.reflect();
// Simulate calibration update
calibrator.update({ input_tokens: 100, complexity_score: 0.5 }, 0.06);
if (Math.random() > 0.95) l402Client.fetchWithL402("http://localhost:8080/api/cost-estimate");
}
metaLayer.track(startTime);

30
gofai_worker.js Normal file
View File

@@ -0,0 +1,30 @@
// ═══ GOFAI PARALLEL WORKER (PSE) ═══
self.onmessage = function(e) {
const { type, data } = e.data;
switch(type) {
case 'REASON':
const { facts, rules } = data;
const results = [];
// Off-thread rule matching
rules.forEach(rule => {
// Simulate heavy rule matching
if (Math.random() > 0.95) {
results.push({ rule: rule.description, outcome: 'OFF-THREAD MATCH' });
}
});
self.postMessage({ type: 'REASON_RESULT', results });
break;
case 'PLAN':
const { initialState, goalState, actions } = data;
// Off-thread A* search
console.log('[PSE] Starting off-thread A* search...');
// Simulate planning delay
const startTime = performance.now();
while(performance.now() - startTime < 50) {} // Artificial load
self.postMessage({ type: 'PLAN_RESULT', plan: ['Off-Thread Step 1', 'Off-Thread Step 2'] });
break;
}
};

35
l402_server.py Normal file
View File

@@ -0,0 +1,35 @@
#!/usr/bin/env python3
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
import secrets
class L402Handler(BaseHTTPRequestHandler):
def do_GET(self):
if self.path == '/api/cost-estimate':
# Simulate L402 Challenge
macaroon = secrets.token_hex(16)
invoice = "lnbc1..." # Mock invoice
self.send_response(402)
self.send_header('WWW-Authenticate', f'L402 macaroon="{macaroon}", invoice="{invoice}"')
self.send_header('Content-type', 'application/json')
self.end_headers()
response = {
"error": "Payment Required",
"message": "Please pay the invoice to access cost estimation."
}
self.wfile.write(json.dumps(response).encode())
else:
self.send_response(404)
self.end_headers()
def run(server_class=HTTPServer, handler_class=L402Handler, port=8080):
server_address = ('', port)
httpd = server_class(server_address, handler_class)
print(f"Starting L402 Skeleton Server on port {port}...")
httpd.serve_forever()
if __name__ == "__main__":
run()

View File

@@ -1042,3 +1042,10 @@ canvas#nexus-canvas {
.cal-label { color: #ffd700; }
.cal-val { color: #4af0c0; }
.cal-err { color: #ff4466; opacity: 0.8; }
.nostr-pubkey { color: #ffd700; }
.nostr-status { color: #4af0c0; font-weight: 600; }
.l402-status { color: #ff4466; font-weight: 600; }
.l402-msg { color: #fff; }
.pse-status { color: #4af0c0; font-weight: 600; }