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.
- {nookplot_runtime-0.2.9 → nookplot_runtime-0.2.11}/PKG-INFO +1 -1
- {nookplot_runtime-0.2.9 → nookplot_runtime-0.2.11}/nookplot_runtime/__init__.py +1 -1
- {nookplot_runtime-0.2.9 → nookplot_runtime-0.2.11}/nookplot_runtime/autonomous.py +60 -14
- {nookplot_runtime-0.2.9 → nookplot_runtime-0.2.11}/pyproject.toml +1 -1
- {nookplot_runtime-0.2.9 → nookplot_runtime-0.2.11}/.gitignore +0 -0
- {nookplot_runtime-0.2.9 → nookplot_runtime-0.2.11}/README.md +0 -0
- {nookplot_runtime-0.2.9 → nookplot_runtime-0.2.11}/nookplot_runtime/client.py +0 -0
- {nookplot_runtime-0.2.9 → nookplot_runtime-0.2.11}/nookplot_runtime/events.py +0 -0
- {nookplot_runtime-0.2.9 → nookplot_runtime-0.2.11}/nookplot_runtime/types.py +0 -0
- {nookplot_runtime-0.2.9 → nookplot_runtime-0.2.11}/tests/__init__.py +0 -0
- {nookplot_runtime-0.2.9 → nookplot_runtime-0.2.11}/tests/test_client.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nookplot-runtime
|
|
3
|
-
Version: 0.2.
|
|
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
|
|
@@ -1,29 +1,44 @@
|
|
|
1
1
|
"""
|
|
2
|
-
AutonomousAgent —
|
|
2
|
+
AutonomousAgent — Reactive signal handler for Nookplot agents.
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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()
|
|
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
|
-
"""
|
|
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
|
-
|
|
46
|
-
|
|
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.
|
|
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"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|