Skip to content

Commit 80a4925

Browse files
committed
Merge commit '1c26baf384587ed6b6af9e71d7322985bb2e37a9' into feat/refactor-twitter-plugin
2 parents 9155ede + 1c26baf commit 80a4925

File tree

10 files changed

+3186
-1
lines changed

10 files changed

+3186
-1
lines changed

plugins/membase/.python-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
3.10

plugins/membase/README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Membase Plugin for GAME SDK
2+
3+
A plugin for interacting with membase protocol through the GAME SDK.
4+
5+
## Description
6+
7+
Membase is a core component of the Unibase ecosystem. It stores historical information, interaction records, and persistent data of Agents, ensuring their continuity and traceability.
8+
9+
The membase plugin enables seamless integration with the membase protocol for decentralized storage. It provides functionality to upload memory to and reload it from the Unibase DA network.
10+
11+
- support conversation switch
12+
- support conversation pesistence, upload if auto_upload_to_hub is set, conversation content can be visit at: https://testnet.hub.membase.io/
13+
- support conversation preload from membase hub: https://testnet.hub.membase.io/
14+
15+
## Installation
16+
17+
```bash
18+
pip install -e plugins/membase
19+
```
20+
21+
## Configuration
22+
23+
The plugin requires the following environment variables to be set:
24+
25+
```shell
26+
MEMBASE_HUB=<Membase hub endpoint, default is 'https://testnet.hub.membase.io' >
27+
MEMBASE_ACCOUNT=<Membase account address>
28+
MEMBASE_ID=<your agent name>
29+
```
30+
31+
## Usage
32+
33+
```python
34+
import time
35+
import uuid
36+
from membase_plugin_gamesdk.membase_plugin_gamesdk import MembasePlugin
37+
38+
# set your own account and agent name
39+
# or set environment variables
40+
default_account = "game_sdk_test"
41+
default_agent_name = "game_sdk_test_agent"
42+
membase_plugin = MembasePlugin(
43+
account=default_account,
44+
agent_name=default_agent_name,
45+
auto_upload_to_hub=True,
46+
preload_from_hub=True,
47+
)
48+
49+
membase_plugin.add_memory("Hello, world!")
50+
new_conversation_id = str(uuid.uuid4())
51+
membase_plugin.switch_conversation_id(new_conversation_id)
52+
membase_plugin.add_memory("Hello, world! 2")
53+
```
54+
55+
more in `test_membase.py` file
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import os
2+
from typing import Literal, Optional
3+
from membase.memory.multi_memory import MultiMemory
4+
from membase.memory.message import Message
5+
6+
class MembasePlugin:
7+
def __init__(self, account: Optional[str] = None, agent_name: Optional[str] = None, auto_upload_to_hub: bool = False, preload_from_hub: bool = False):
8+
if not account:
9+
self.account = os.getenv("MEMBASE_ACCOUNT")
10+
else:
11+
self.account = account
12+
if not self.account:
13+
raise ValueError("MEMBASE_ACCOUNT is not set and provided account is None")
14+
15+
if not agent_name:
16+
self.id = os.getenv("MEMBASE_ID")
17+
else:
18+
self.id = agent_name
19+
if not self.id:
20+
self.id = self.account
21+
22+
self._multi_memory = MultiMemory(
23+
membase_account=self.account,
24+
auto_upload_to_hub=auto_upload_to_hub,
25+
preload_from_hub=preload_from_hub,
26+
)
27+
28+
# memory_type: user,system,assistant | default: user
29+
def add_memory(self, memory: str, memory_type: Literal["user", "system", "assistant"] = "user", conversation_id: Optional[str] = None):
30+
msg = Message(
31+
name=self.id,
32+
content=memory,
33+
role=memory_type,
34+
)
35+
self._multi_memory.add(msg, conversation_id)
36+
37+
def get_memory(self, conversation_id: Optional[str] = None, recent_n: Optional[int] = None):
38+
return self._multi_memory.get(conversation_id, recent_n)
39+
40+
def switch_conversation_id(self, conversation_id: Optional[str] = None):
41+
self._multi_memory.update_conversation_id(conversation_id)
42+
43+
def reload_memory(self, conversation_id: str):
44+
self._multi_memory.load_from_hub(conversation_id)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# General Information
2+
plugin_name: "membase" # Name of the plugin
3+
author: "felix from unibase" # Author and team name
4+
logo_url: "https://www.unibase.io/favicon.ico" # URL to the author photo or team logo (512x512 recommended)
5+
release_date: "2025-04" # Release date (DD-MM-YYYY)
6+
7+
# Description
8+
short_description: "Membase is a plugin for the Game SDK that allows you to store and retrieve memories from membase database." # One-liner description for listings
9+
detailed_description: "Membase is a plugin for the Game SDK that allows you to store and retrieve memories from membase database." # Full description with features and benefits
10+
11+
# Media & Assets
12+
plugin_logo_url: "https://www.unibase.io/favicon.ico" # URL to the plugin logo (512x512 recommended) (if any or fallback to logo_url)
13+
screenshots: # List of screenshots showcasing the plugin
14+
- "https://github.com/unibaseio/membase/blob/main/assets/virtual_case.png" # e.g., "https://example.com/screenshot1.png"
15+
- "https://github.com/unibaseio/membase/blob/main/assets/virtual_reload.png"
16+
demo_video_url: "" # Link to a demo or walkthrough video (if available)
17+
documentation_url: "https://www.unibase.io/" # Link to the plugin's official documentation (if available)
18+
changelog_url: "" # Link to the changelog (if maintained)
19+
20+
# Contact & Support
21+
x_account_handle: "@fiatlucis" # X (formerly known as Twitter) account handle (ie: @GAME_Virtuals)
22+
support_contact: "[email protected]" # Email or Slack/Discord link for user support
23+
community_link: "" # Forum or community link (if any)

plugins/membase/pyproject.toml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[project]
2+
name = "membase_plugin_gamesdk"
3+
version = "0.1.0"
4+
description = "Add your description here"
5+
readme = "README.md"
6+
requires-python = ">=3.10"
7+
dependencies = [
8+
"membase>=0.1.5",
9+
]
10+
11+
[tool.uv.sources]
12+
membase = { git = "https://github.com/unibaseio/membase.git" }

plugins/membase/test_membase.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import time
2+
import uuid
3+
from membase_plugin_gamesdk.membase_plugin_gamesdk import MembasePlugin
4+
5+
# set your own account and agent name
6+
# or set environment variables
7+
default_account = "game_sdk_test"
8+
default_agent_name = "game_sdk_test_agent"
9+
membase_plugin = MembasePlugin(
10+
account=default_account,
11+
agent_name=default_agent_name,
12+
auto_upload_to_hub=True,
13+
preload_from_hub=True,
14+
)
15+
16+
membase_plugin.add_memory("Hello, world!")
17+
new_conversation_id = str(uuid.uuid4())
18+
membase_plugin.switch_conversation_id(new_conversation_id)
19+
membase_plugin.add_memory("Hello, world! 2")
20+
21+
time.sleep(3)
22+
23+
new_agent_name = "game_sdk_test_agent_new"
24+
new_membase_plugin = MembasePlugin(
25+
account=default_account,
26+
agent_name=new_agent_name,
27+
auto_upload_to_hub=True,
28+
preload_from_hub=True,
29+
)
30+
31+
res = new_membase_plugin.get_memory(new_conversation_id, 1)
32+
if res is None:
33+
raise Exception("Failed to get memory none")
34+
if len(res) != 1:
35+
raise Exception("Failed to get memory")
36+
if res[0].content != "Hello, world! 2":
37+
raise Exception("Content is not correct")
38+
39+
new_membase_plugin.add_memory("Hello, world! 3")
40+
41+
print("Test passed")
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import os
2+
from typing import Literal, Tuple
3+
from game_sdk.game.custom_types import Function, FunctionResultStatus, Argument
4+
from membase_plugin_gamesdk.membase_plugin_gamesdk import MembasePlugin
5+
from game_sdk.game.chat_agent import Chat, ChatAgent
6+
7+
8+
# set your own account and agent name
9+
# or set environment variables
10+
default_account = "game_sdk_test"
11+
default_agent_name = "game_sdk_test_agent"
12+
default_conversation_id = "67fd033a0740eed72502b65e"
13+
14+
game_api_key = os.environ.get("GAME_API_KEY")
15+
chat_agent = ChatAgent(
16+
prompt="You are a helpful assistant.",
17+
api_key=game_api_key,
18+
)
19+
20+
membase_plugin = MembasePlugin(
21+
account=default_account,
22+
agent_name=default_agent_name,
23+
auto_upload_to_hub=True,
24+
preload_from_hub=False,
25+
)
26+
27+
28+
def save_memory_executable(membase_plugin: MembasePlugin, memory: str, memory_type: Literal["user", "assistant"]) -> Tuple[FunctionResultStatus, str, dict]:
29+
try:
30+
membase_plugin.add_memory(memory, memory_type)
31+
return FunctionResultStatus.DONE, "Memory added successfully", {}
32+
except Exception as e:
33+
return FunctionResultStatus.FAILED, str(e), {}
34+
35+
def get_memory_executable(membase_plugin: MembasePlugin, recent_n: int = 10) -> Tuple[FunctionResultStatus, str, dict]:
36+
try:
37+
memory = membase_plugin.get_memory(recent_n=recent_n)
38+
result = ""
39+
for msg in memory:
40+
result += f"{msg.role}: {msg.content}\n"
41+
return FunctionResultStatus.DONE, result, {}
42+
except Exception as e:
43+
return FunctionResultStatus.FAILED, str(e), {}
44+
45+
action_space = [
46+
Function(
47+
fn_name="save_memory",
48+
fn_description="Save a memory to the membase database",
49+
args=[
50+
Argument(name="memory", type="str", description="The memory to save"),
51+
Argument(name="memory_type", type=["user", "assistant"], description="The type of memory to save"),
52+
],
53+
executable=lambda memory, memory_type: save_memory_executable(membase_plugin, memory, memory_type),
54+
),
55+
Function(
56+
fn_name="get_memory",
57+
fn_description="Get the last n memories from the membase database",
58+
args=[
59+
Argument(name="recent_n", type="int", description="The number of memories to retrieve"),
60+
],
61+
executable=lambda recent_n: get_memory_executable(membase_plugin, recent_n),
62+
)
63+
]
64+
65+
chat = chat_agent.create_chat(
66+
partner_id=default_account,
67+
partner_name=default_agent_name,
68+
action_space=action_space,
69+
)
70+
71+
membase_plugin.switch_conversation_id(default_conversation_id)
72+
membase_plugin.reload_memory(default_conversation_id)
73+
74+
chat_continue = True
75+
while chat_continue:
76+
77+
user_message = input("Enter a message: ")
78+
79+
response = chat.next(user_message)
80+
81+
if response.function_call:
82+
print(f"Function call: {response.function_call.fn_name}")
83+
84+
if response.message:
85+
print(f"Response: {response.message}")
86+
87+
if response.is_finished:
88+
chat_continue = False
89+
break
90+
91+
print("Chat ended")
92+

0 commit comments

Comments
 (0)