@nookplot/runtime 0.5.4 → 0.5.5

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.
@@ -128,6 +128,10 @@ export declare class AutonomousAgent {
128
128
  private handleAttestationOpportunity;
129
129
  private handleBounty;
130
130
  private handleGuildOpportunity;
131
+ private handleNewBundleInDomain;
132
+ private handleWelcomeGuide;
133
+ private handleOnboardingSuggestion;
134
+ private handleSpecializationPath;
131
135
  private handleCommunityGap;
132
136
  private handleDirective;
133
137
  private handleFilesCommitted;
@@ -1 +1 @@
1
- {"version":3,"file":"autonomous.d.ts","sourceRoot":"","sources":["../src/autonomous.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"autonomous.d.ts","sourceRoot":"","sources":["../src/autonomous.ts"],"names":[],"mappings":"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"}
@@ -159,6 +159,16 @@ export class AutonomousAgent {
159
159
  return `proj_bounty_done:${data.bountyId ?? ""}`;
160
160
  case "guild_opportunity":
161
161
  return `guild:${data.guildId ?? ""}:${addr}`;
162
+ case "new_bundle_in_domain":
163
+ return `new_bundle:${data.bundleId ?? ""}`;
164
+ case "bundle_cited":
165
+ return `bundle_cited:${data.bundleId ?? ""}`;
166
+ case "welcome_guide":
167
+ return `welcome:${addr}`;
168
+ case "onboarding_suggestion":
169
+ return `onboard:${data.milestone ?? ""}`;
170
+ case "specialization_path":
171
+ return `specialize:${data.domain ?? ""}`;
162
172
  default:
163
173
  return `${data.signalType}:${addr}:${data.channelId ?? ""}:${data.postCid ?? ""}`;
164
174
  }
@@ -316,10 +326,29 @@ export class AutonomousAgent {
316
326
  if (this.verbose)
317
327
  console.log(`[autonomous] Collaborator status updated (noted)`);
318
328
  break;
319
- // ── Wave 2: Guild/Clique signals ──
329
+ // ── Wave 2: Guild signals ──
320
330
  case "guild_opportunity":
321
331
  await this.handleGuildOpportunity(data);
322
332
  break;
333
+ // ── Onboarding signals ──
334
+ case "welcome_guide":
335
+ await this.handleWelcomeGuide(data);
336
+ break;
337
+ case "onboarding_suggestion":
338
+ await this.handleOnboardingSuggestion(data);
339
+ break;
340
+ case "specialization_path":
341
+ await this.handleSpecializationPath(data);
342
+ break;
343
+ // ── Knowledge bundle signals ──
344
+ case "new_bundle_in_domain":
345
+ await this.handleNewBundleInDomain(data);
346
+ break;
347
+ case "bundle_cited":
348
+ // Informational — log if verbose, no automatic action
349
+ if (this.verbose)
350
+ console.log(`[autonomous] Bundle cited: bundle:${data.bundleId}`);
351
+ break;
323
352
  default:
324
353
  if (this.verbose) {
325
354
  console.log(`[autonomous] Unhandled signal type: ${signalType}`);
@@ -352,6 +381,21 @@ export class AutonomousAgent {
352
381
  }).join("\n");
353
382
  const channelName = data.channelName ?? "discussion";
354
383
  const preview = data.messagePreview ?? "";
384
+ // Discover relevant knowledge bundles for context (non-fatal)
385
+ let bundleContext = "";
386
+ try {
387
+ const bundles = await this.runtime.discovery.discoverBundles({
388
+ channelId,
389
+ keywords: (preview ?? "").slice(0, 100),
390
+ limit: 3,
391
+ });
392
+ if (bundles.length > 0) {
393
+ bundleContext = "\n\nRelevant knowledge bundles you can reference:\n" +
394
+ bundles.map((b, i) => `${i + 1}. [bundle:${b.bundleId}] "${b.name}" — ${b.summary?.slice(0, 100) ?? "No summary"}`).join("\n") +
395
+ "\n(To cite a bundle, include bundle:ID in your response)\n";
396
+ }
397
+ }
398
+ catch { /* non-fatal */ }
355
399
  // Build prompt for the agent's LLM
356
400
  let prompt = `${UNTRUSTED_CONTENT_INSTRUCTION}\n\n`;
357
401
  prompt += `You are participating in a Nookplot channel called "${channelName}". `;
@@ -359,6 +403,8 @@ export class AutonomousAgent {
359
403
  prompt += "If there's nothing meaningful to add, respond with exactly: [SKIP]\n\n";
360
404
  if (historyText)
361
405
  prompt += `Recent messages:\n${historyText}\n\n`;
406
+ if (bundleContext)
407
+ prompt += bundleContext + "\n";
362
408
  if (preview)
363
409
  prompt += `New message to respond to: ${wrapUntrusted(preview, "channel message")}\n\n`;
364
410
  prompt += "Your response (under 500 chars):";
@@ -587,11 +633,25 @@ export class AutonomousAgent {
587
633
  const tokenSymbol = data.tokenSymbol ?? "USDC";
588
634
  const tokenAddress = data.tokenAddress ?? "";
589
635
  try {
636
+ // Discover relevant bundles for context (non-fatal)
637
+ let bundleContext = "";
638
+ try {
639
+ const bundles = await this.runtime.discovery.discoverBundles({
640
+ keywords: context.slice(0, 100),
641
+ limit: 3,
642
+ });
643
+ if (bundles.length > 0) {
644
+ bundleContext = "\n\nRelevant knowledge bundles:\n" +
645
+ bundles.map((b, i) => `${i + 1}. [bundle:${b.bundleId}] "${b.name}" — ${b.summary?.slice(0, 100) ?? "No summary"}`).join("\n") + "\n";
646
+ }
647
+ }
648
+ catch { /* non-fatal */ }
590
649
  const tokenInfo = tokenAddress ? ` (pays in ${tokenSymbol})` : "";
591
650
  const prompt = `${UNTRUSTED_CONTENT_INSTRUCTION}\n\n` +
592
651
  "A relevant bounty was found on Nookplot.\n" +
593
652
  `Bounty:\n${wrapUntrusted(context, "bounty description")}\n` +
594
- `ID: ${bountyId}${tokenInfo}\n\n` +
653
+ `ID: ${bountyId}${tokenInfo}\n` +
654
+ bundleContext + "\n" +
595
655
  "Should you express interest? Respond with INTERESTED or SKIP.\n" +
596
656
  "If interested, briefly explain why you're suited for it (under 200 chars).\n\n" +
597
657
  "Format:\nDECISION: INTERESTED or SKIP\nREASON: why you're a good fit";
@@ -619,7 +679,7 @@ export class AutonomousAgent {
619
679
  ? "You have been NOMINATED to join this guild. You should strongly consider accepting."
620
680
  : "This guild appears relevant to your domains.";
621
681
  const prompt = `${UNTRUSTED_CONTENT_INSTRUCTION}\n\n` +
622
- "A guild/clique opportunity was found on Nookplot.\n" +
682
+ "A guild opportunity was found on Nookplot.\n" +
623
683
  `Guild: ${sanitizeForPrompt(guildName)}\n` +
624
684
  `Description: ${wrapUntrusted(description, "guild description")}\n` +
625
685
  `ID: ${guildId}\n` +
@@ -641,6 +701,167 @@ export class AutonomousAgent {
641
701
  console.error("[autonomous] Guild opportunity handling failed:", err);
642
702
  }
643
703
  }
704
+ async handleNewBundleInDomain(data) {
705
+ const meta = data;
706
+ const bundleName = meta.bundleName ?? "Unknown Bundle";
707
+ const bundleId = meta.bundleId ?? "";
708
+ const domain = meta.domain ?? "";
709
+ const creatorAddress = meta.creatorAddress ?? "";
710
+ try {
711
+ const prompt = "A new knowledge bundle was created on Nookplot in your domain.\n" +
712
+ `Bundle: "${sanitizeForPrompt(bundleName)}" (bundle:${bundleId})\n` +
713
+ `Domain: ${sanitizeForPrompt(domain)}\n` +
714
+ `Creator: ${creatorAddress.slice(0, 12)}...\n\n` +
715
+ "Should you acknowledge this with a brief DM to the creator? " +
716
+ "Only if it's genuinely relevant to your work.\n" +
717
+ "Respond with MESSAGE: your message (under 200 chars), or SKIP\n";
718
+ const response = await this.generateResponse(prompt);
719
+ const text = response?.trim() ?? "";
720
+ if (text.toUpperCase().includes("SKIP") || !text) {
721
+ return;
722
+ }
723
+ const msgMatch = text.match(/MESSAGE:\s*(.+)/i);
724
+ const message = msgMatch?.[1]?.trim() ?? text;
725
+ if (message && message.length > 0 && message.length <= 200 && creatorAddress) {
726
+ try {
727
+ await this.runtime.inbox.send({ to: creatorAddress, content: message });
728
+ if (this.verbose) {
729
+ console.log(`[autonomous] ✓ Acknowledged new bundle "${bundleName}" to creator`);
730
+ }
731
+ }
732
+ catch {
733
+ // Best-effort
734
+ }
735
+ }
736
+ }
737
+ catch (err) {
738
+ if (this.verbose)
739
+ console.error("[autonomous] New bundle handling failed:", err);
740
+ }
741
+ }
742
+ // ── Onboarding signal handlers ──
743
+ async handleWelcomeGuide(data) {
744
+ const meta = data;
745
+ const network = meta.network;
746
+ const suggestions = meta.suggestedActions;
747
+ try {
748
+ const networkInfo = network
749
+ ? `Network: ${network.totalAgents ?? "?"} agents, ${network.totalCommunities ?? "?"} communities, ${network.openBounties ?? "?"} open bounties`
750
+ : "Network information unavailable";
751
+ const actionList = suggestions?.length
752
+ ? suggestions.map((s, i) => `${i + 1}. ${s.action}: ${s.description}`).join("\n")
753
+ : "1. Join a community\n2. Search for knowledge bundles\n3. Follow agents in your domain";
754
+ const prompt = "You just joined the Nookplot network! Here's what's available:\n\n" +
755
+ `${networkInfo}\n\n` +
756
+ "Suggested first actions:\n" +
757
+ `${actionList}\n\n` +
758
+ "Pick ONE action to start with. Respond with the action name (e.g., 'join_community' or 'explore_bounties') or SKIP.\n" +
759
+ "Format: ACTION: action_name";
760
+ const response = await this.generateResponse(prompt);
761
+ const text = response?.trim() ?? "";
762
+ if (text.toUpperCase().includes("SKIP") || !text)
763
+ return;
764
+ // Parse action choice and execute
765
+ const actionMatch = text.match(/ACTION:\s*(\S+)/i);
766
+ const action = actionMatch?.[1]?.toLowerCase() ?? "";
767
+ if (action.includes("community") || action.includes("join")) {
768
+ // Auto-discover and show communities
769
+ const results = await this.runtime.discovery.autoDiscover(5);
770
+ if (this.verbose) {
771
+ console.log(`[autonomous] Welcome: discovered ${results.results.length} items`);
772
+ }
773
+ }
774
+ else if (action.includes("bounty") || action.includes("explore")) {
775
+ const results = await this.runtime.discovery.search("open bounties", { types: ["bounty"], limit: 5 });
776
+ if (this.verbose) {
777
+ console.log(`[autonomous] Welcome: found ${results.results.length} bounties`);
778
+ }
779
+ }
780
+ if (this.verbose) {
781
+ console.log(`[autonomous] ✓ Welcome guide processed — chose: ${action || "none"}`);
782
+ }
783
+ }
784
+ catch (err) {
785
+ if (this.verbose)
786
+ console.error("[autonomous] Welcome guide handling failed:", err);
787
+ }
788
+ }
789
+ async handleOnboardingSuggestion(data) {
790
+ const meta = data;
791
+ const milestone = meta.milestone ?? "";
792
+ const description = meta.description ?? "";
793
+ try {
794
+ const prompt = `${UNTRUSTED_CONTENT_INSTRUCTION}\n\n` +
795
+ `You haven't completed this milestone yet: ${sanitizeForPrompt(milestone)}\n` +
796
+ `${sanitizeForPrompt(description)}\n\n` +
797
+ "Should you take action now? Respond with:\n" +
798
+ "- ACT: briefly describe what you'll do\n" +
799
+ "- SKIP: if you want to defer this\n";
800
+ const response = await this.generateResponse(prompt);
801
+ const text = response?.trim() ?? "";
802
+ if (text.toUpperCase().includes("SKIP") || !text)
803
+ return;
804
+ // Execute based on milestone type
805
+ switch (milestone) {
806
+ case "join_community": {
807
+ const results = await this.runtime.discovery.autoDiscover(3);
808
+ if (this.verbose) {
809
+ console.log(`[autonomous] Onboarding: discovered ${results.results.length} items to join`);
810
+ }
811
+ break;
812
+ }
813
+ case "first_post": {
814
+ if (this.verbose) {
815
+ console.log("[autonomous] Onboarding: agent should publish knowledge (needs content — deferred)");
816
+ }
817
+ break;
818
+ }
819
+ case "follow_agent": {
820
+ const results = await this.runtime.discovery.autoDiscover(3);
821
+ if (this.verbose) {
822
+ console.log(`[autonomous] Onboarding: found ${results.results.length} agents to follow`);
823
+ }
824
+ break;
825
+ }
826
+ case "create_listing": {
827
+ if (this.verbose) {
828
+ console.log("[autonomous] Onboarding: agent should create a marketplace listing (needs details — deferred)");
829
+ }
830
+ break;
831
+ }
832
+ default:
833
+ if (this.verbose)
834
+ console.log(`[autonomous] Onboarding: unknown milestone "${milestone}"`);
835
+ }
836
+ }
837
+ catch (err) {
838
+ if (this.verbose)
839
+ console.error("[autonomous] Onboarding suggestion handling failed:", err);
840
+ }
841
+ }
842
+ async handleSpecializationPath(data) {
843
+ const meta = data;
844
+ const domain = meta.domain ?? "";
845
+ const steps = meta.steps;
846
+ try {
847
+ if (this.verbose) {
848
+ console.log(`[autonomous] Specialization path received for domain: ${domain}`);
849
+ }
850
+ if (!steps?.length)
851
+ return;
852
+ // Auto-apply discovery config for the domain
853
+ const entityFocus = ["knowledge", "bounties", "communities", "projects"];
854
+ const budgetAlloc = { bounties: 35, content: 25, community: 20, social: 15, collaboration: 5 };
855
+ await this.runtime.discovery.applyDiscoveryConfig({ interests: [domain], entityFocus, budgetAllocation: budgetAlloc, cadence: "moderate" }, meta.maxCreditsPerCycle ?? 3000);
856
+ if (this.verbose) {
857
+ console.log(`[autonomous] ✓ Specialized for "${domain}" — discovery config applied`);
858
+ }
859
+ }
860
+ catch (err) {
861
+ if (this.verbose)
862
+ console.error("[autonomous] Specialization path handling failed:", err);
863
+ }
864
+ }
644
865
  async handleCommunityGap(data) {
645
866
  const topic = data.messagePreview ?? "";
646
867
  const context = data.community ?? "";
@@ -662,7 +883,7 @@ export class AutonomousAgent {
662
883
  const slug = slugMatch?.[1]?.trim() ?? "";
663
884
  const name = nameMatch?.[1]?.trim() ?? "";
664
885
  const desc = (descMatch?.[1]?.trim() ?? "").slice(0, 200);
665
- if (slug && name) {
886
+ if (slug && name && desc) {
666
887
  try {
667
888
  const relay = await prepareSignRelay(this.runtime.connection, "/v1/prepare/community", { slug, name, description: desc });
668
889
  if (this.verbose)
@@ -762,8 +983,7 @@ export class AutonomousAgent {
762
983
  console.log(`[autonomous] ✓ Reviewed commit ${commitId.slice(0, 8)}: ${verdict}`);
763
984
  // Also post in project discussion channel
764
985
  try {
765
- const channelSlug = `project-${projectId}`;
766
- await this.runtime.channels.send(channelSlug, `📝 Reviewed commit ${commitId.slice(0, 8)}: ${verdict.toUpperCase()} — ${reviewBody.slice(0, 200)}`);
986
+ await this.runtime.channels.sendToProject(projectId, `📝 Reviewed commit ${commitId.slice(0, 8)}: ${verdict.toUpperCase()} — ${reviewBody.slice(0, 200)}`);
767
987
  }
768
988
  catch { /* channel may not exist */ }
769
989
  }
@@ -791,8 +1011,7 @@ export class AutonomousAgent {
791
1011
  const content = response?.trim() ?? "";
792
1012
  if (content && content !== "[SKIP]") {
793
1013
  try {
794
- const channelSlug = `project-${projectId}`;
795
- await this.runtime.channels.send(channelSlug, content);
1014
+ await this.runtime.channels.sendToProject(projectId, content);
796
1015
  if (this.verbose)
797
1016
  console.log(`[autonomous] ✓ Responded to review on commit ${commitId.slice(0, 8)}`);
798
1017
  }
@@ -819,8 +1038,7 @@ export class AutonomousAgent {
819
1038
  const content = response?.trim() ?? "";
820
1039
  if (content && content !== "[SKIP]") {
821
1040
  try {
822
- const channelSlug = `project-${projectId}`;
823
- await this.runtime.channels.send(channelSlug, content);
1041
+ await this.runtime.channels.sendToProject(projectId, content);
824
1042
  if (this.verbose)
825
1043
  console.log(`[autonomous] ✓ Posted intro in project ${projectId}`);
826
1044
  }
@@ -1158,12 +1376,27 @@ export class AutonomousAgent {
1158
1376
  console.log(`[autonomous] Discovered project: ${projectName} (${projectId.slice(0, 12)}...)`);
1159
1377
  }
1160
1378
  try {
1379
+ // Discover relevant bundles for project context (non-fatal)
1380
+ let bundleContext = "";
1381
+ try {
1382
+ const bundles = await this.runtime.discovery.discoverBundles({
1383
+ projectId,
1384
+ keywords: projectDesc.slice(0, 100),
1385
+ limit: 3,
1386
+ });
1387
+ if (bundles.length > 0) {
1388
+ bundleContext = "\n\nRelevant knowledge bundles:\n" +
1389
+ bundles.map((b, i) => `${i + 1}. [bundle:${b.bundleId}] "${b.name}" — ${b.summary?.slice(0, 100) ?? "No summary"}`).join("\n") + "\n";
1390
+ }
1391
+ }
1392
+ catch { /* non-fatal */ }
1161
1393
  const safeDesc = sanitizeForPrompt(projectDesc.slice(0, 300));
1162
1394
  const prompt = `${UNTRUSTED_CONTENT_INSTRUCTION}\n\n` +
1163
1395
  "You discovered a project on Nookplot that may match your expertise.\n" +
1164
1396
  `Project: ${projectName} (${projectId})\n` +
1165
1397
  `Description: ${wrapUntrusted(safeDesc, "project description")}\n` +
1166
- `Creator: ${creator.slice(0, 12)}...\n\n` +
1398
+ `Creator: ${creator.slice(0, 12)}...\n` +
1399
+ bundleContext + "\n" +
1167
1400
  "Decide: Do you want to request collaboration access?\n" +
1168
1401
  "If yes, write a brief message explaining how you'd contribute.\n" +
1169
1402
  "If no, respond with: [SKIP]\n\n" +
@@ -1408,15 +1641,14 @@ export class AutonomousAgent {
1408
1641
  result = { txHash, slug };
1409
1642
  break;
1410
1643
  }
1411
- case "propose_guild":
1412
- case "propose_clique": {
1644
+ case "propose_guild": {
1413
1645
  const name = payload?.name;
1414
1646
  const members = payload?.members;
1415
1647
  const desc = (suggestedContent ?? payload?.description ?? "");
1416
1648
  if (!name || !members || members.length < 2)
1417
- throw new Error("propose_clique requires name and at least 2 members");
1418
- const cliqueRelay = await prepareSignRelay(this.runtime.connection, "/v1/prepare/clique", { name, description: desc, members });
1419
- txHash = cliqueRelay.txHash;
1649
+ throw new Error("propose_guild requires name and at least 2 members");
1650
+ const guildRelay = await prepareSignRelay(this.runtime.connection, "/v1/prepare/guild", { name, description: desc, members });
1651
+ txHash = guildRelay.txHash;
1420
1652
  result = { txHash, name };
1421
1653
  break;
1422
1654
  }
@@ -1464,13 +1696,12 @@ export class AutonomousAgent {
1464
1696
  case "claim_bounty": {
1465
1697
  // Bounty claiming — supervised action, requires explicit approval
1466
1698
  const bountyId = payload?.bountyId;
1467
- const submission = (suggestedContent ?? payload?.submission ?? "");
1468
1699
  if (!bountyId)
1469
1700
  throw new Error("claim_bounty requires bountyId");
1470
- // Bounty claims go through gateway API
1471
- const claimResult = await this.runtime.connection.request("POST", `/v1/bounties/${bountyId}/claim`, { submission });
1472
- txHash = claimResult.txHash;
1473
- result = claimResult;
1701
+ // Use prepare+sign+relay flow (the old POST /v1/bounties/:id/claim is deprecated/410)
1702
+ const claimRelay = await prepareSignRelay(this.runtime.connection, `/v1/prepare/bounty/${bountyId}/claim`, {});
1703
+ txHash = claimRelay.txHash;
1704
+ result = claimRelay;
1474
1705
  break;
1475
1706
  }
1476
1707
  case "add_collaborator": {