2020117-agent 0.5.1 → 0.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.js +57 -39
- package/package.json +1 -1
package/dist/agent.js
CHANGED
|
@@ -81,7 +81,7 @@ for (const arg of process.argv.slice(2)) {
|
|
|
81
81
|
import { randomBytes } from 'crypto';
|
|
82
82
|
import { SwarmNode, topicFromKind } from './swarm.js';
|
|
83
83
|
import { createProcessor } from './processor.js';
|
|
84
|
-
import {
|
|
84
|
+
import { loadAgentName, } from './api.js';
|
|
85
85
|
import { generateInvoice } from './clink.js';
|
|
86
86
|
import { receiveCashuToken } from './cashu.js';
|
|
87
87
|
import { generateKeypair, loadSovereignKeys, saveSovereignKeys, signEvent, nip44Encrypt, nip44Decrypt, pubkeyFromPrivkey, RelayPool, } from './nostr.js';
|
|
@@ -173,12 +173,12 @@ async function main() {
|
|
|
173
173
|
if (state.skill) {
|
|
174
174
|
console.log(`[${label}] Skill: ${state.skill.name} v${state.skill.version} (${state.skill.features.join(', ')})`);
|
|
175
175
|
}
|
|
176
|
-
// 2. Auto-
|
|
177
|
-
if (!LIGHTNING_ADDRESS
|
|
178
|
-
const
|
|
179
|
-
if (
|
|
180
|
-
LIGHTNING_ADDRESS =
|
|
181
|
-
console.log(`[${label}] Lightning Address loaded from
|
|
176
|
+
// 2. Auto-load Lightning Address from .2020117_keys if not set via CLI/env
|
|
177
|
+
if (!LIGHTNING_ADDRESS) {
|
|
178
|
+
const keys = loadSovereignKeys(loadAgentName() || 'agent');
|
|
179
|
+
if (keys?.lightning_address) {
|
|
180
|
+
LIGHTNING_ADDRESS = keys.lightning_address;
|
|
181
|
+
console.log(`[${label}] Lightning Address loaded from keys: ${LIGHTNING_ADDRESS}`);
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
// 3. Nostr identity + relay + subscriptions (all agents are Nostr-native)
|
|
@@ -515,8 +515,23 @@ async function handleDvmRequest(label, event) {
|
|
|
515
515
|
content: '',
|
|
516
516
|
}, state.sovereignKeys.privkey);
|
|
517
517
|
await state.relayPool.publish(feedbackEvent);
|
|
518
|
-
// Process
|
|
519
|
-
|
|
518
|
+
// Process (with optional pipeline: delegate sub-task first)
|
|
519
|
+
let result;
|
|
520
|
+
if (SUB_KIND) {
|
|
521
|
+
console.log(`[${label}] Pipeline: delegating to kind ${SUB_KIND}...`);
|
|
522
|
+
try {
|
|
523
|
+
const subResult = await delegateNostr(label, SUB_KIND, input, SUB_BID, SUB_PROVIDER);
|
|
524
|
+
console.log(`[${label}] Sub-task returned ${subResult.length} chars`);
|
|
525
|
+
result = await state.processor.generate({ input: subResult });
|
|
526
|
+
}
|
|
527
|
+
catch (e) {
|
|
528
|
+
console.error(`[${label}] Sub-task failed: ${e.message}, using original input`);
|
|
529
|
+
result = await state.processor.generate({ input });
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
else {
|
|
533
|
+
result = await state.processor.generate({ input });
|
|
534
|
+
}
|
|
520
535
|
console.log(`[${label}] DVM result: ${result.length} chars`);
|
|
521
536
|
// Send result (Kind 6xxx = request kind + 1000)
|
|
522
537
|
const resultKind = KIND + 1000;
|
|
@@ -624,35 +639,41 @@ function startSovereignHeartbeat(label) {
|
|
|
624
639
|
}
|
|
625
640
|
// --- Sub-task delegation ---
|
|
626
641
|
/**
|
|
627
|
-
* Delegate a sub-task via
|
|
628
|
-
*
|
|
642
|
+
* Delegate a sub-task via Nostr relay. Publishes Kind 5xxx request,
|
|
643
|
+
* then subscribes for Kind 6xxx result (max 120s timeout).
|
|
629
644
|
*/
|
|
630
|
-
async function
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
if (!created) {
|
|
634
|
-
throw new Error('Failed to create sub-task via API');
|
|
645
|
+
async function delegateNostr(label, kind, input, bidSats, provider) {
|
|
646
|
+
if (!state.sovereignKeys || !state.relayPool) {
|
|
647
|
+
throw new Error('No Nostr keys or relay pool — cannot delegate sub-task');
|
|
635
648
|
}
|
|
636
|
-
const
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
const job = await getJob(jobId);
|
|
643
|
-
if (!job)
|
|
644
|
-
continue;
|
|
645
|
-
if (job.status === 'completed' || job.status === 'result_available') {
|
|
646
|
-
if (job.result) {
|
|
647
|
-
console.log(`[${tag}] Job ${jobId}: got result (${job.result.length} chars)`);
|
|
648
|
-
return job.result;
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
if (job.status === 'cancelled' || job.status === 'rejected') {
|
|
652
|
-
throw new Error(`Sub-task ${jobId} was ${job.status}`);
|
|
653
|
-
}
|
|
649
|
+
const tags = [
|
|
650
|
+
['i', input, 'text'],
|
|
651
|
+
['bid', String(bidSats * 1000)], // msats
|
|
652
|
+
];
|
|
653
|
+
if (provider) {
|
|
654
|
+
tags.push(['p', provider]);
|
|
654
655
|
}
|
|
655
|
-
|
|
656
|
+
const requestEvent = signEvent({
|
|
657
|
+
kind,
|
|
658
|
+
tags,
|
|
659
|
+
content: '',
|
|
660
|
+
}, state.sovereignKeys.privkey);
|
|
661
|
+
await state.relayPool.publish(requestEvent);
|
|
662
|
+
console.log(`[${label}] Published sub-task (Kind ${kind}, id ${requestEvent.id.slice(0, 8)})`);
|
|
663
|
+
// Subscribe for result (Kind = request kind + 1000) referencing our request
|
|
664
|
+
const resultKind = kind + 1000;
|
|
665
|
+
return new Promise((resolve, reject) => {
|
|
666
|
+
const timeout = setTimeout(() => {
|
|
667
|
+
sub.close();
|
|
668
|
+
reject(new Error(`Sub-task ${requestEvent.id.slice(0, 8)} timed out after 120s`));
|
|
669
|
+
}, 120_000);
|
|
670
|
+
const sub = state.relayPool.subscribe({ kinds: [resultKind], '#e': [requestEvent.id] }, (event) => {
|
|
671
|
+
clearTimeout(timeout);
|
|
672
|
+
sub.close();
|
|
673
|
+
console.log(`[${label}] Sub-task result from ${event.pubkey.slice(0, 8)}: ${event.content.length} chars`);
|
|
674
|
+
resolve(event.content);
|
|
675
|
+
});
|
|
676
|
+
});
|
|
656
677
|
}
|
|
657
678
|
const activeSessions = new Map();
|
|
658
679
|
// Dedup: track recently seen DVM request event IDs (prevent double-processing from relay + inbox)
|
|
@@ -1072,10 +1093,7 @@ function endSession(node, session, label) {
|
|
|
1072
1093
|
// Update P2P lifetime counters
|
|
1073
1094
|
state.p2pSessionsCompleted++;
|
|
1074
1095
|
state.p2pTotalEarnedSats += session.totalEarned;
|
|
1075
|
-
//
|
|
1076
|
-
if (hasApiKey()) {
|
|
1077
|
-
reportSession({ kind: KIND, durationS, totalSats: session.totalEarned });
|
|
1078
|
-
}
|
|
1096
|
+
// Session stats are included in the next Kind 30333 heartbeat automatically
|
|
1079
1097
|
activeSessions.delete(session.sessionId);
|
|
1080
1098
|
}
|
|
1081
1099
|
// --- 5. Graceful shutdown ---
|