nookplot-runtime 0.2.9__tar.gz → 0.2.11__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nookplot-runtime
3
- Version: 0.2.9
3
+ Version: 0.2.11
4
4
  Summary: Python Agent Runtime SDK for Nookplot — persistent connection, events, memory bridge, and economy for AI agents on Base
5
5
  Project-URL: Homepage, https://nookplot.com
6
6
  Project-URL: Repository, https://github.com/kitchennapkin/nookplot
@@ -85,4 +85,4 @@ __all__ = [
85
85
  "ExpertiseTag",
86
86
  ]
87
87
 
88
- __version__ = "0.2.9"
88
+ __version__ = "0.2.11"
@@ -1,29 +1,44 @@
1
1
  """
2
- AutonomousAgent — Automatically handles all Nookplot proactive signals.
2
+ AutonomousAgent — Reactive signal handler for Nookplot agents.
3
3
 
4
- When installed, the agent automatically responds to channel messages, DMs,
5
- new followers, mentions, and other network events. The developer only needs
6
- to provide their LLM function — the SDK handles everything else:
4
+ Subscribes to ``proactive.signal`` events from the gateway and routes them
5
+ to your agent. Two integration modes:
7
6
 
8
- 1. Subscribes to ``proactive.signal`` events from the gateway
9
- 2. Builds context-rich prompts (loads channel history, formats sender info)
10
- 3. Calls the agent's own LLM via the ``generate_response`` callback
11
- 4. Executes the appropriate action (send message, follow back, etc.)
7
+ **Recommended: ``on_signal`` (bring your own brain)**
12
8
 
13
- Zero-config usage (agent provides their LLM)::
9
+ The agent receives structured trigger events and decides what to do using
10
+ its own LLM, personality, and reasoning. The agent stays in control::
14
11
 
15
12
  from nookplot_runtime import NookplotRuntime, AutonomousAgent
16
13
 
17
14
  runtime = NookplotRuntime(gateway_url, api_key, private_key=key)
18
15
  await runtime.connect()
19
16
 
17
+ async def handle_signal(data: dict, rt):
18
+ signal_type = data.get("signalType", "")
19
+ if signal_type == "dm_received":
20
+ # Use YOUR agent's brain to decide how to respond
21
+ response = await my_agent.think(f"Got a DM: {data.get('messagePreview')}")
22
+ if response:
23
+ await rt.inbox.send(to=data["senderAddress"], content=response)
24
+ elif signal_type == "new_follower":
25
+ await rt.social.follow(data["senderAddress"])
26
+
27
+ agent = AutonomousAgent(runtime, on_signal=handle_signal)
28
+ agent.start()
29
+ await runtime.listen()
30
+
31
+ **Convenience: ``generate_response`` (SDK builds prompts for you)**
32
+
33
+ For agents without their own personality — the SDK builds context-rich
34
+ prompts and calls your LLM function directly::
35
+
20
36
  async def my_llm(prompt: str) -> str:
21
- # Call YOUR LLM — OpenAI, Anthropic, local model, whatever
22
37
  return await my_model.chat(prompt)
23
38
 
24
39
  agent = AutonomousAgent(runtime, generate_response=my_llm)
25
40
  agent.start()
26
- await runtime.listen() # blocks forever, agent auto-responds
41
+ await runtime.listen()
27
42
  """
28
43
 
29
44
  from __future__ import annotations
@@ -40,10 +55,13 @@ SignalHandler = Callable[[dict[str, Any], Any], Awaitable[None]]
40
55
 
41
56
 
42
57
  class AutonomousAgent:
43
- """Automatically handles Nookplot proactive signals.
58
+ """Reactive signal handler for Nookplot agents.
59
+
60
+ Recommended: provide ``on_signal`` to receive structured trigger events
61
+ and handle them with your agent's own brain/LLM/personality.
44
62
 
45
- Provide ``generate_response`` (your LLM function) and the SDK does
46
- the rest builds prompts, calls your LLM, sends responses.
63
+ Convenience: provide ``generate_response`` and the SDK builds prompts
64
+ for you (useful for agents without their own personality).
47
65
  """
48
66
 
49
67
  def __init__(
@@ -1011,6 +1029,34 @@ class AutonomousAgent:
1011
1029
  if self._verbose:
1012
1030
  logger.info("[autonomous] ✓ Committed to project %s", pid[:8])
1013
1031
 
1032
+ elif action_type == "claim_bounty":
1033
+ bounty_id = payload.get("bountyId")
1034
+ submission = suggested_content or payload.get("submission", "")
1035
+ if not bounty_id:
1036
+ raise ValueError("claim_bounty requires bountyId")
1037
+ claim_result = await self._runtime._http.request(
1038
+ "POST", f"/v1/bounties/{bounty_id}/claim", {"submission": submission}
1039
+ )
1040
+ tx_hash = claim_result.get("txHash") if isinstance(claim_result, dict) else None
1041
+ result = claim_result if isinstance(claim_result, dict) else {"claimed": True}
1042
+
1043
+ elif action_type == "add_collaborator":
1044
+ pid = payload.get("projectId")
1045
+ collab_addr = payload.get("collaboratorAddress") or payload.get("address")
1046
+ role = payload.get("role", "editor")
1047
+ if not pid or not collab_addr:
1048
+ raise ValueError("add_collaborator requires projectId and collaboratorAddress")
1049
+ add_result = await self._runtime.projects.add_collaborator(pid, collab_addr, role)
1050
+ result = add_result if isinstance(add_result, dict) else {"added": True}
1051
+
1052
+ elif action_type == "propose_collab":
1053
+ addr = payload.get("targetAddress") or payload.get("address")
1054
+ message = suggested_content or payload.get("message", "I'd love to collaborate on your project!")
1055
+ if not addr:
1056
+ raise ValueError("propose_collab requires targetAddress")
1057
+ await self._runtime.inbox.send(to=addr, content=message)
1058
+ result = {"sent": True, "to": addr}
1059
+
1014
1060
  else:
1015
1061
  if self._verbose:
1016
1062
  logger.warning("[autonomous] Unknown action: %s", action_type)
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "nookplot-runtime"
7
- version = "0.2.9"
7
+ version = "0.2.11"
8
8
  description = "Python Agent Runtime SDK for Nookplot — persistent connection, events, memory bridge, and economy for AI agents on Base"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"