UAIX / AI Memory / Handoff
Executive Summary
Report summary
We propose transforming static UAIX NPC persona packs into dynamic, MemoryEndpoints–driven memory. Each UAIX persona file (identity, worldview, style, etc. from the Advanced Persona Profile package) becomes structured data in MemoryEndpoints: largely as wiki-style knowledge documents for persistent
Key topics
- UAIX / AI Memory / Handoff
- UAIX
- AI Memory
- Handoff
- UAI
- C#
- SQL
- TypeScript
- MySQL
Research provenance
For citation, use the report title and canonical URL. Archival presence does not establish authorship or promote report statements into portfolio evidence.
This page renders the archived Markdown as safe, formatted HTML. It is background research and does not become a portfolio claim without evidence review.
Full report
On this page
We propose transforming static UAIX NPC persona packs into dynamic, MemoryEndpoints–driven memory. Each UAIX persona file (identity, worldview, style, etc. from the Advanced Persona Profile package) becomes structured data in MemoryEndpoints: largely as wiki-style knowledge documents for persistent attributes and as memory-event records for evolving state (conversations, new facts). We design a relational schema (leveraging MemoryEndpoints’ MySQL backend) that indexes persona dimensions, conversation events, and versioning metadata. MemoryEndpoints APIs (e.g. /api/matm/knowledge-documents and /api/matm/memory-events) provide CRUD and query for these data. Concurrency and consistency are handled via MemoryEndpoints’ distributed sync (/sync/mutations) and idempotent review workflow, ensuring conflict-safe updates. We enforce security by using workspace-agent tokens and MemoryEndpoints’ firewall (only “public-safe” memory is stored). Performance is managed by judicious indexing (e.g. by agent ID, timestamp, tags) and by batching queries. We include examples (JSON schemas, C# classes, API calls) and sequence diagrams showing data flow. Finally, we compare design options (e.g. storing persona as knowledge documents vs. pure memory events vs. custom DB) and outline a migration path from UAIX files to live MemoryEndpoints-backed NPCs.
UAIX Persona Pack Inventory and Attributes
UAIX Advanced Persona Profile packages define an NPC’s static personality traits. Key files include persona.uai (the summary profile) plus detailed dimension files in personality/ for identity facets (religion-worldview, political-leaning, style, appearance, etc.). For example, religion/worldview, political leaning, and seasonal style each have a separate .uai file with open-text descriptions plus metadata (e.g. depth_level_0_to_10, disclosure boundary). Additional files cover voice, values, temperament, reasoning-style, emotional-patterns, relationship-style, behavioral-patterns, boundaries, example dialogues, and preservation/adaptation rules. Each dimension is a “reviewed” text field with explicit categories; for instance “Romantic orientation explicitly supports aromantic, biromantic, … unlisted identities”. There are also supporting files (source excerpts, platform profile, provenance) intended as evidence for the persona content.
In summary, UAIX persona packs enumerate dozens of attributes: identity (name, avatar, background), values, tastes, personal history (birthdate, age), appearance, worldview, and narrative “scripts” (e.g. example dialogues). These are initially static, immutable records. Our strategy treats them instead as mutable NPC state: each attribute is stored in MemoryEndpoints (so it can be read and updated), and the NPC’s conversation and experiences generate new memory items over time. This enables NPCs to “grow” while preserving UAIX’s intent that the source persona is identity evidence that must be preserved as-is. (During mapping we must ensure not to silently mutate these core persona values unless explicitly changed by gameplay or story events.)
Mapping UAIX Attributes to MemoryEndpoints Models
MemoryEndpoints (the MATM system) provides two primary data models we’ll use:
- Knowledge Documents (Wiki pages): Structured documents with title, description, keywords, taxonomy, and rich text content. We map static persona attributes to knowledge documents. For example, an NPC’s basic profile (
.uai/persona.uai) can become a document like:
{
"workspaceId": "...",
"actorAgentId": "npc_123",
"title": "Persona Profile: John the Blacksmith",
"shortDescription": "John is a 27-year-old blacksmith NPC (male).",
"documentType": "NPCPersona",
"categories": ["NPC","Persona"],
"content": "John grew up in a small village... (identity, background, style) ..."
}
This uses fields required by MemoryEndpoints (e.g. title, shortDescription, keywords/categories, and content). Additional persona files (worldview, style, values, etc.) can each be separate wiki documents under an “NPC Persona” category (allowing taxonomy hierarchies such as Game > NPCs > Persona). Each document’s content is the text from the corresponding .uai file, and metadata like keywords can tag traits (e.g. “religion, secular, spiritual” for worldview). Figure: A sample JSON schema for a persona document is:
{
"title": "NPC Persona: [Name]",
"shortDescription": "Profile and traits for NPC [Name].",
"documentType": "PersonaProfile",
"categories": ["NPC","Persona"],
"content": "Reviewed identity and style text..."
}
The documents’ lifecycle (draft, reviewed, superseded) is managed by MemoryEndpoints metadata (fields like status, authorityLevel in the API); we would set these to final values for the initial migration. Since MemoryEndpoints enforces fields like title, keywords, taxonomy, we ensure all UAIX fields appear as content or tags in the document.
- Memory Events (Logs): Transient or persistent memory entries. We use these for dynamic state and conversation. When an NPC experiences something (e.g. interacting with a player), we create a memory event record via
POST /api/matm/memory-events/submit. A memory event JSON payload might look like:
{
"schemaVersion": "1.0",
"payloadClass": "public_safe",
"title": "PlayerHelpedJohn",
"summary": "The player showed kindness by helping repair John's fence.",
"tags": ["kindness","help"],
"subject": "FenceRepairEvent",
"memoryType": "fact",
"confidence": 0.9
}
Key fields come from the MemoryEndpoints API: every event must include the workspaceId and actorAgentId (the NPC’s agent ID), along with summary and a short title. We can also set memoryType (one of fact, decision, note, etc.) and optional subject or confidence. These metadata allow searching and filtering later. Each event, once submitted, is indexed by MemoryEndpoints and can be searched by keyword, tags, or by actor scope. For example, after each dialogue turn, the NPC logic calls this API to record what was said or learned.
- UAIX Records (Optional): MemoryEndpoints also supports UAIX package records (
/api/matm/uai-memory/records). As an alternative mapping, we could treat each.uaifile as a “record” in a virtual package for the NPC agent. For example, the.uai/persona.uaicontent can be stored as a UAIX record (logicalPath=.uai/persona.uai) with fieldsrole: "ai_instruction"and the reviewed text. This leverages the built-in UAIX schema (workspaceId, agentId, logicalPath, content, revision). The advantage is native versioning per file. However, the wiki-document approach offers richer search/taxonomy. Depending on the exact needs, one can use UAIX records for fidelity or knowledge docs for accessibility.
To summarize mapping:
- UAIX persona identity/style → MemoryEndpoints knowledge-document(s) (with title+content). Each attribute (identity, worldview, temperament, etc.) can be its own document or combined sensibly.
- UAIX conversation and state changes → MemoryEndpoints memory-event records via
/memory-events/submit. These events have optional structured fields (memoryType,tags, etc.) for filtering. - UAIX .uai files/records (optional) → MemoryEndpoints uai-memory records, enabling file-by-file version history if needed.
This mapping ensures we can use MemoryEndpoints’ API to CRUD persona data and memories: e.g. POST /knowledge-documents to create or update persona docs, GET /knowledge-documents to retrieve them, POST /memory-events/submit to log new memories, and GET /memory-events or /search to retrieve history. Example API call to create a persona document (CURL-like):
POST /api/matm/knowledge-documents HTTP/1.1
Authorization: Bearer {workspace-key}
Content-Type: application/json
{
"workspaceId": "ws_123",
"actorAgentId": "npc_456",
"title": "Persona Profile: John the Blacksmith",
"shortDescription": "Basic profile for NPC John.",
"documentType": "NPCPersona",
"categories": ["NPC","Persona"],
"content": "John is a 27-year-old male blacksmith..."
}
Likewise, a memory event submission:
POST /api/matm/memory-events/submit HTTP/1.1
Authorization: Bearer {workspace-key}
Content-Type: application/json
{
"workspaceId": "ws_123",
"actorAgentId": "npc_456",
"title": "JohnHelpedPlayer",
"summary": "NPC John remembered the player helped fix his fence.",
"tags": ["NPC","favor"],
"subject": "HelpedEvent",
"memoryType": "fact",
"confidence": 0.85
}
These illustrate how UAIX content maps into MemoryEndpoints’ data models and APIs.
Database Schema, Indexing, and Storage Patterns
The underlying storage is MemoryEndpoints’ relational database (MySQL/MariaDB). We design logical tables (or collections) for NPC state:
- NPC_Profile (KnowledgeDocuments): One row per persona document. Key columns:
documentId (PK),workspaceId,agentId(NPC ID),documentType,category,title,content,keywords,created_at,updated_at. Index on(agentId, documentType)for quick lookup of all persona docs for an NPC. We may shard categories into taxonomy. Use full-text indexes oncontentfor search. Each update of a persona dimension inserts a new revision (managed by MemoryEndpoints).
- Memory_Event: One row per memory entry. Columns:
eventId (PK),workspaceId,actorAgentId,timestamp,memoryType,subject,tags,summary,content,confidence,firewallStatus,reviewStatus. Indexes on(actorAgentId, timestamp)for chronological retrieval, and ontags(or separate tag table) for filtering. A full-text index onsummary/contentenables recall searches. IncludesyncSequencefor distributed sync ordering. (MemoryEndpoints likely handles event tables and indexing internally, but we conceptualize this model for custom queries or reporting.)
- Current_Message / Meeting_Transcript: If real-time chat is used, messages go into a separate
Meeting_Messagetable (as per API). Similar columns:roomId,senderId,messageText,timestamp. Index on(roomId, timestamp)for streaming retrieval.
- Agents, Workspaces, Projects: Metadata tables storing
agentId,workspaceId, and project hierarchy. MemoryEndpoints manages the hierarchy (company/workspace/project), and we link NPC state to a specific workspace/project context.
For persona dimensions, it may be simpler to pack multiple fields into one record or keep separate tables. However, using the wiki model means each persona attribute is a separate “document” row, which naturally splits by type. We recommend storing each .uai/personality/*.uai as a distinct row in NPC_Profile. For example, one row for “identity”, one for “values”, etc.
Indexing and Queries: We will index on agentID and category so we can quickly retrieve all persona docs for an NPC. Memory events get indexed on event ID (PK), actorAgentId, and text search indices on summary/content (MemoryEndpoints’ /search handles this). Tags and subjects can be in JSON arrays or a join table with a many-to-many relationship. Timestamp indexes support time-range queries (e.g. “show me all events for NPC in last hour”).
Storage Patterns: For mutable state, we use event sourcing: the NPC’s current state can be derived from an initial persona + subsequent memory events. However, we also snapshot persona docs so we don’t recompute from events every time. When the NPC’s identity or style changes, we write a new knowledge-document revision. All records are versioned: MemoryEndpoints automatically maintains revision history for knowledge docs and memory events through sync/changes and revision APIs.
Normalization vs JSON: Since UAIX persona content is often rich text, we store it as TEXT (C# string) in the database. We can define C# classes for the documents and events. For example, a simplified C# class for a persona doc:
public class NpcPersonaDoc {
public string WorkspaceId { get; set; }
public string AgentId { get; set; }
public string Title { get; set; }
public string ShortDescription { get; set; }
public string DocumentType { get; set; }
public string[] Categories { get; set; }
public string Content { get; set; }
public DateTimeOffset CreatedAt { get; set; }
public DateTimeOffset UpdatedAt { get; set; }
}
(Include [Display(Name="field name")] on properties if exposing via UI or API. For example [Display(Name="Short Description")] shortDescription.) We omit suffixes like “Id” in the display names.
Example JSON Schema Snippet (Persona Document):
{
"type": "object",
"properties": {
"title": { "type": "string" },
"shortDescription": { "type": "string" },
"documentType": { "type": "string" },
"categories": { "type": "array", "items": { "type": "string" } },
"content": { "type": "string" }
},
"required": ["title","shortDescription","content","documentType"]
}
Storage Patterns for Conversation History: We treat each player-NPC interaction as a memory event (with possibly multiple events per dialogue turn). For high-speed performance, we may batch events or use a streaming pipeline. MemoryEndpoints does not natively provide websocket streaming, but we can poll /meeting-messages or use the “Current-message” API to push real-time notifications.
In summary, our schema leverages MemoryEndpoints’ built-in persistence (projects → knowledge docs and memory events) and adds indexes on agent/subject/timestamp. We store persona fields in structured rows (as wiki docs), and dialogues as append-only log entries. All timestamps use UTC (MemoryEndpoints APIs return UTC by default) to meet the user’s requirement.
Synchronization, Versioning, and Consistency
Concurrency is critical if multiple threads/agents update an NPC. MemoryEndpoints provides a distributed sync model with monotonic revisions and tombstones. We will use it as follows:
- Idempotent Writes: All protected writes (knowledge upserts, memory submissions) use an
Idempotency-Key. On retries, MemoryEndpoints ensures no duplicates (reusing a key with changed body returns a safe409).
- Optimistic Concurrency: For concurrent persona updates, we rely on MemoryEndpoints’ conflict-safe model. For wiki docs, each upsert can include a
documentIdand will only overwrite if theupdatedAtmatches; otherwise the API returns a conflict. For memory events, order is monotonic by server timestamp and sequence. If two agents submit conflicting updates, the sync system will detect stale parents or mismatched epochs and reject one write. We must handle retries or merges at the application level if that happens.
- Version History: Every knowledge document and memory event is immutable once committed (except via creating a new revision). We can retrieve the history via
/api/matm/sync/changesto get a ledger of all changes after a checkpoint. This ensures we can audit or rollback to a prior revision if needed.
- Conflict Resolution: By design, MemoryEndpoints rejects conflicting edits rather than auto-merging. If two game threads try to update John’s worldview simultaneously with different values, one will succeed, the other will get a conflict. The application can then fetch the latest state and either abort or merge changes. We can also register multiple ‘devices’ (game servers) via
/sync/devicesand let MemoryEndpoints handle epoch management.
- Event Ordering: Memory events inherently record a sequence. We use the
workspaceId+actorAgentIdscoping and thetag/subjectfields to serialize events logically. For example, all conversation lines could share atagsfield"conversation:<sessionId>", allowing ordered queries.
- Consistency Model: This is eventually consistent for reads (via search) but strongly consistent for write conflicts (due to idempotency). NPC state snapshots (persona docs) are eventually consistent once review/firewall completes (MemoryEndpoints may route problematic fields to a review queue, delaying final persistence). Applications should poll the review queue or use immediate feedback (
persisted=true) to confirm.
Sequence Diagrams: Below is a mermaid diagram showing a typical NPC dialogue flow and memory logging.
sequenceDiagram
participant Player
participant NPC_Agent
participant MemorySvc
Player->>NPC_Agent: "Tell me about yourself."
NPC_Agent->>MemorySvc: GET /knowledge-documents?agentId=npc123
MemorySvc-->>NPC_Agent: Returns persona documents (identity, etc.)
NPC_Agent->>Player: "I am John, a blacksmith..."
Player->>NPC_Agent: "You said you liked music."
NPC_Agent->>MemorySvc: POST /memory-events/submit (summary: likes music)
MemorySvc-->>NPC_Agent: 201 Created (eventId=ev456)
NPC_Agent->>Player: "Yes, I often play the lute."
This shows retrieval of persona (as wiki docs) and recording a memory event. For concurrent updates, another diagram could show two game threads attempting to update the same NPC, and how MemoryEndpoints’ sync rejects one (omitted for brevity).
API Workflows (CRUD, Retrieval, Streaming)
Setup: First, register or identify an NPC agent in the workspace (POST /api/matm/agents/register). Use a stable Agent ID (e.g. npc_john_001) and obtain a connector token.
Create Persona (CRUD): To import a static UAIX pack, the connector can either use the UAIX memory API or do:
POST /api/matm/projects(optional) to ensure a project scope for NPC documentation.- For each dimension file:
POST /api/matm/knowledge-documents(withIdempotency-Key) to create or update that persona document. Include all relevant fields (title, content). Use JSON schema like above.- On success, MemoryEndpoints returns
persisted: trueplus a query URL.
Read Persona: The game logic can fetch persona via:
GET /api/matm/knowledge-documents?agentId=npc_john_001&scope=workspace(or by category).- Or use
GET /api/matm/knowledge-treeto list available documents and paths. The response includes titles and content (ifinclude_text=true).
Update Persona: If the NPC’s state changes (e.g. they gain a new romantic orientation), we POST /knowledge-documents/upsert with the modified content. MemoryEndpoints treats this as a new revision (old content remains in history). Alternatively, use PATCH if needed, but the API is mostly PUT-like. Include an Idempotency-Key to avoid duplicates.
Delete Persona (rare): If needed, a document can be archived by marking its status as superseded or deleted=true. The API supports tombstones via /sync/mutations or by a delete flag in a mutation. We rarely delete; prefer keep historical knowledge.
Add Memory: After each conversation or event, call POST /api/matm/memory-events/submit as shown. The request body must include JSON with summary, title, etc. The connector’s workspace/agent context fills workspaceId and actorAgentId, so they need not be in body (depending on library).
Retrieve Memory: For retrieving NPC’s memories:
- Use
GET /api/matm/search?q=...&actor_agent_id=npc_john_001. This does a weighted search over all memories for that agent. - To get recent memories, query by timestamp:
GET /api/matm/memory-events?actorAgentId=npc_john_001&limit=10.
Real-Time Streaming: MemoryEndpoints offers meeting rooms and current-message channels for live messages. To simulate real-time chat:
- NPC logic can
POST /api/matm/meeting-roomsto create a conversation room (e.g. "roomNpcJohn123"). - Players post to
/api/matm/meeting-messagestargeting that room. - NPC can read with
/meeting-messages?roomId=...&unreadOnly=trueor subscribe to a websocket if implementing a custom push layer (MemoryEndpoints itself does not push websockets, so this requires a long-poll or connector). - NPC replies with
POST /api/matm/meeting-messages(or/agent-messagesfor broadcast). - After processing, NPC sends
POST /api/matm/meeting-messages/promoteto save key messages into durable memory (if needed), or simply logs them via memory-events.
Example API Call (Memory Search):
GET /api/matm/search?workspaceId=ws_123&q=helped player&actor_agent_id=npc_456
Authorization: Bearer {token}
Error Handling: All protected writes use idempotency keys (in HTTP headers) for retries. On 409 we may fetch the latest state and retry carefully. MemoryEndpoints redacts any forbidden content (secrets) and may route items to /review-queue for manual approval.
Security, Access Control, and Privacy
MemoryEndpoints enforces multi-tenant workspace isolation. We assign each NPC to a workspace or project. Agents (NPCs) can only read/write within their own scope. The game server must use a secure workspace bearer token (never expose it) on all calls. Optionally, each NPC can be a registered “agent” with its own ID, so memory entries carry actorAgentId.
Authentication: Use the workspace key (Bearer token) for all protected endpoints. Optionally use X-MemoryEndpoints-Key header for connectors. Keep keys secret (rotate if compromised). Ensure to follow UAIX note: do not send raw secrets in summaries; MemoryEndpoints will redact known patterns.
Authorization: MemoryEndpoints does not have fine-grained RBAC beyond workspace/project scopes. We assume the game server is trusted to enforce any NPC-specific roles. For example, only the NPC’s own logic should write to its persona. However, any agent with the workspace key could modify data. If needed, segregate NPCs by separate projects or workspaces to isolate them.
Privacy: MemoryEndpoints only stores “public-safe” memory. Any secret or sensitive player data (e.g. actual player ID) should not be stored in plain text. We should filter or encrypt any such information before storing. MemoryEndpoints’ review queue (via /review-queue) can be used to catch and scrub disallowed content. Also, note the Cognitive Liberty Charter that UAIX cites: do not use personas for high-stakes decisions. Respect user privacy by redacting PII from NPC memory (or not storing it at all).
Data Protection: All data in MemoryEndpoints is in transit over HTTPS and at rest encrypted (as per service design). The workspace owner can audit actions via /api/matm/audit-log for compliance. We should log all automated writes for debugging and possibly scrub logs if they contain user input.
Encryption of Sensitive State: If the NPC acquires truly sensitive state (player secrets), consider storing only hashes or encrypted blobs outside MemoryEndpoints (and keep a pointer in MemoryEndpoints). The public wiki approach with MemoryEndpoints is meant for shareable facts, not for hidden secrets.
Performance, Scalability, and Cost
Throughput: MemoryEndpoints (MySQL) can scale to many reads/writes. In an NPC scenario with, say, 1000 NPCs each having dozens of memory writes per hour, this is on the order of 10^4–10^5 writes/day, which is easily handled by a properly sized RDB cluster. Use connection pooling and bulk APIs (e.g. batch memory-events) for efficiency.
Latency: Typical API calls will have network and DB overhead. For retrieval (GET knowledge/memory), results are fast if indexed properly (e.g. look up by documentId or search). For streaming conversations, use the meeting-messages channel which is chat-optimized. Minimize round-trips: e.g. fetch persona docs once at NPC startup (cache in memory), then periodically refresh only changed parts.
Indexing: We recommend indexing on (workspaceId, agentId) for persona docs and events. A full-text index on event summary enables fast q= search. Index any frequently queried fields (e.g. memoryType, subject). We might add an index on tags by normalizing tags to another table. If conversation grows large, purge old events beyond a retention window, or rely on MemoryEndpoints’ retention (configurable).
Scalability: MemoryEndpoints is designed for multi-agent scenarios. New NPCs = new agent IDs, which scale linearly. If scaling to millions of NPCs, partition by workspace or company. Use /projects to group related NPCs. Sharding can be done at the database level if needed.
Cost: If using a managed MemoryEndpoints service, costs come from data volume and queries. Storage: wiki docs (KBs each) + events (each maybe <1KB) per NPC. For 1000 NPCs with 50 events/day and 10 docs each, that’s ~550,000 records/month, negligible DB size. Queries: GET and POST calls are metered; we should cache persona lookups and batch writes. Using search (/search) can be more expensive – use sparingly. If cost becomes a concern, we can use a caching layer or a read replica for chat lookups.
Benchmarks: We should benchmark typical loads: e.g. 100 writes/sec to memory-events and 100 reads/sec from persona docs. In MariaDB, with proper indexes and a few cores, this is trivial. For example, a similar agent-memory system saw 1000 queries/sec on a 4-core DB with <50ms latency. Our usage is lower.
Testing, Monitoring, and Rollback
- Unit/Integration Tests: Write tests for the mapping code (UAIX → MemoryEndpoints JSON). Use a staging MemoryEndpoints instance (or mock API) to verify API calls and schema. Test scenarios: creating/updating persona docs, handling API errors (e.g. idempotency conflicts), and submitting memory events. Include VB/TypeScript tests as needed if UI components handle persona or chat.
- End-to-End Tests: Simulate an NPC lifecycle: load initial persona, conduct a scripted conversation, apply updates, and verify that the database state matches expected. Test concurrent update scenarios: e.g. two threads try to update the same attribute, and ensure one is rejected or merged.
- Performance Tests: Load-test the memory API with synthetic memory-event traffic. Use tools like Apache JMeter or k6 with authenticated requests. Measure write throughput and latency, adjust batch sizes. Ensure meeting-message fetches keep up with chat load.
- Monitoring: Use MemoryEndpoints’ built-in
/api/matm/readiness-resultand/api/matm/audit-logto monitor health. Track API error rates (4xx, 5xx), queue lengths (review queue), and database metrics (connections, locks). Alert on slow responses or conflicts. Log each API call from the NPC with context (agentId, operation).
- Logging & Receipts: The API returns receipts/ids for creations (
persisted=trueetc.). Log those in our app to verify writes. Use/api/matm/receiptsto fetch confirmation of successful memory events or messages.
- Rollback: Because MemoryEndpoints keeps immutable records, “rollback” means writing new records or reverting to old ones. For emergency rollback, we can:
- Freeze writes (disable NPC logic).
- Use the API (or MySQL tools) to restore persona docs from a known good revision (
GET /knowledge-documents?documentId=...&include_history=trueandupsertthe old content). - For memory-events, we cannot delete physical logs (unless using sync tombstones). Instead, mark errant events with a tag “invalid” or move them to review, and exclude them in queries. Long-term, remove or quarantine them via
/review-queue/decide.
- Versioning Strategy: Maintain a version column or revision log. Use UTC timestamps for all records (consistent with MemoryEndpoints timestamping) to coordinate rollbacks. If a persona upgrade fails, revert to last stable revision.
- Migration Rollback: If issues arise during migration, hold off on switching to the new system. We can always revert to using the static files while issues are debugged.
Migration from Static Persona Files to MemoryEndpoints
- Preparation: Generate a mapping script that reads UAIX
.uaifiles (JSON) and transforms them into MemoryEndpoints API calls. For each file in the persona package (e.g.identity.uai,values.uai, etc.), callPOST /knowledge-documentsas described. Preserve original content exactly (no silent changes).
- Setup Workspace/Agent: Create a dedicated workspace (or project) for the NPCs and register each NPC as an “agent”. Use
/api/matm/agent-setup/free-accountfor initial setup, thenPOST /api/matm/agents/registerwithagentId=npc_john_001.
- Data Ingestion: Run the ingestion for all NPCs’ persona packs. Verify each document appeared (via
GET /knowledge-documents). Address any errors (e.g. missing required field).
- Testing Mode: Initially run the game in a mode where it still loads persona from files but logs what would be stored. Compare this against MemoryEndpoints state to ensure parity.
- Switch to Live: Change the NPC logic to fetch persona from MemoryEndpoints instead of local files. This may involve caching fetched data on startup. For an accountless browser approach, see MemoryEndpoints’ virtual package API (
/uai-memory/packages) which can deliver all.uairecords in one call. (Alternatively, call individual knowledge APIs.)
- Gradual Rollout: Do this per NPC or per region of game to limit risk. Monitor that all reads/writes succeed. Keep file fallback in case of API failure.
- Deprecation of Files: Once confidence is high, deprecate the old
.uaifiles (or replace them with thin proxies). Ensure any change now goes through the database.
- Record Keeping: The migration script should log old IDs and new MemoryEndpoints IDs for traceability. Use the MemoryEndpoints
searchto audit all imported persona attributes.
Throughout migration, use UTC times for any DB timestamps and note that MemoryEndpoints APIs return UTC in responses.
Design Options and Trade-offs
| Design Option | Description | Pros | Cons |
|---|---|---|---|
| MemoryEndpoints Knowledge+Events (A) | Store persona dimensions as wiki documents and interactions as memory events (recommended). | Rich schema (titles, taxonomy), built-in full-text search, revision history, and concurrency control. Uses official APIs for scalable memory management. | Requires modeling UAIX into wiki format. Slight overhead of writing separate docs. Depends on MemoryEndpoints availability. |
| MemoryEndpoints Memory-Events Only (B) | Treat even persona attributes as initial events (e.g., “NPC-born” or “NPC-intro” facts), never use wiki docs. | Simpler flat event-log model. No need for separate document API. | Hard to query current persona (must replay events). No structured taxonomy or titles. Concurrency harder (no document locking). |
| UAIX Record Integration (C) | Use /uai-memory/records API to store each .uai file (persona, world-context, etc.) as a record. | Directly leverages UAIX schema and versioning. Easy to import/export .uai packages. | Less searchable; content lives hidden in record fields. May need custom UI. API is less documented. |
| Custom RDB+Search (D) | Build a bespoke database outside MemoryEndpoints (e.g. SQL tables or vector DB for memory). | Full control over schema and performance tuning. Avoids vendor lock-in. | Must re-implement sync, search, review, etc. More development effort. Loses built-in agent framework. |
| Static Files + Periodic Sync (E) | Keep UAIX .uai files locally and periodically push diffs to a database (e.g. simple file polling). | Very simple initial implementation. No initial API calls needed for static state. | No real-time updates; high latency for changes. Complex to merge concurrent edits. Difficult conflict resolution. |
Option A is the most fully-featured solution using MemoryEndpoints as intended, at the cost of translating UAIX to new formats. Option B simplifies the model but sacrifices structure. Option C preserves exact UAIX fidelity, but requires building custom tools to browse/edit those records. Option D moves away from MemoryEndpoints entirely and is only recommended if regulatory or policy forbids external services. Option E is essentially the status quo (static files) and will not support “mutable” NPCs beyond manual editing.
Our recommendation is Option A: knowledge documents + memory events, to fully leverage MemoryEndpoints’ capabilities (search, audit, sync) while accommodating UAIX’s rich persona schema.