Note
This page has been superseded by Distributed Storage — MySQL. Content below is kept for reference.
MySQL State Store¶
agentscope-extensions-mysql persists AgentScope agent state into MySQL. A good fit when you already have a MySQL infrastructure or need transactional / SQL-based access to state data.
Add the dependency¶
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope-extensions-mysql</artifactId>
<version>${agentscope.version}</version>
</dependency>
Bring the matching JDBC driver yourself (e.g. mysql:mysql-connector-j).
Quickstart¶
import com.zaxxer.hikari.HikariDataSource;
import io.agentscope.core.state.AgentStateStore;
import io.agentscope.extensions.mysql.state.MysqlAgentStateStore;
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl("jdbc:mysql://localhost:3306/agentscope?serverTimezone=UTC");
ds.setUsername("root");
ds.setPassword("***");
// Second arg createIfNotExist=true: auto-create database and table
AgentStateStore stateStore = new MysqlAgentStateStore(ds, true);
ReActAgent agent = ReActAgent.builder()
.name("assistant")
.model(model)
.stateStore(stateStore)
.build();
If the database and table are pre-created, use the safer form:
AgentStateStore stateStore = new MysqlAgentStateStore(ds); // throws IllegalStateException if missing
AgentStateStore stateStore = new MysqlAgentStateStore(ds, false); // explicit
Custom database / table names¶
AgentStateStore stateStore = new MysqlAgentStateStore(
ds,
"agentscope_prod", // database name
"session_state", // table name
true // auto-create
);
Database and table names must match [a-zA-Z_][a-zA-Z0-9_-]* and be ≤ 64 chars to avoid SQL injection.
Schema¶
When createIfNotExist=true, the table is created automatically:
CREATE TABLE IF NOT EXISTS agentscope_sessions (
session_id VARCHAR(255) NOT NULL,
state_key VARCHAR(255) NOT NULL,
item_index INT NOT NULL DEFAULT 0,
state_data LONGTEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (session_id, state_key, item_index)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
The
(userId, sessionId)pair is packed into thesession_idcolumn as{userSegment}:{sessionId}(userSegment=userId, or__anon__for anonymous sessions).Single value:
item_index = 0List:
item_index = 0, 1, 2, ...— one row per item; an extra row withstate_key='xxx:_hash'is used for change detection.
Direct API usage¶
MysqlAgentStateStore implements the AgentStateStore interface:
// Single value (userId may be null for anonymous sessions)
stateStore.save("user-42", "session-1", "agent_state", state);
Optional<MyState> got = stateStore.get("user-42", "session-1", "agent_state", MyState.class);
// List (append-only growth; full rewrite on change)
stateStore.save("user-42", "session-1", "messages", listOfMessages);
List<MyState> all = stateStore.getList("user-42", "session-1", "messages", MyState.class);
// Maintenance
boolean exists = stateStore.exists("user-42", "session-1");
stateStore.delete("user-42", "session-1");
Set<String> sessions = stateStore.listSessionIds("user-42"); // null lists anonymous sessions
// Cleanup (use with care, test/ops only)
stateStore.truncateAllSessions();
Configuration¶
Constructor / parameter |
Notes |
|---|---|
|
Required. Recommended: HikariCP / Druid pool |
|
Default |
|
Default |
|
If |
truncateAllSessions()issuesTRUNCATE TABLEand requires DROP privilege; DDL is non-rollbackable, so reserve it for tests or ops cleanup.