Documentation/Unified Store Tools
v2.0.0-beta.1Snapshot bebdcd1Markdown ↗

Unified Store Tools

Unified Store Tools

In v0.5.0, the 19 plugin-specific CRUD tools (memory_store, context_set, instructions_set, user_info_set, etc.) were replaced with 5 generic store_* tools that work across all stores. This reduces tool clutter, simplifies the LLM's decision-making, and makes it trivial to add new stores.

The 5 Generic Tools

Tool Signature Description
store_get store_get(store, key?) Read one value by exact key; omitting key returns a store-specific view, which may contain only metadata
store_set store_set(store, key, data) Create or update an entry
store_delete store_delete(store, key) Remove an entry by key
store_list store_list(store, filter?) List entries with optional filters
store_action store_action(store, action, params?) Store-specific operations (query, clear, etc.)

The store parameter is a string identifying which store to target. The data parameter is an object whose shape depends on the store.

For "notes", a keyless store_get({ store: "notes" }) returns only keys, descriptions, and tiers. Read each source's contents with store_get({ store: "notes", key: "<exact index key>" }), including the displayed tier prefix and any collision suffix. store_list discovers entries omitted from the visible index. Other stores retain their own keyless behavior.

Available Stores

Store Feature Flag Description Data Shape for store_set
"notes" workingMemory: true Tiered working memory (raw/summary/findings) { description, value, tier?, priority? }
"whiteboard" inContextMemory: true Key-value pairs visible directly in LLM context { description, value, priority? } (showInUI is host-owned metadata; see below)
"instructions" persistentInstructions: true Agent instructions persisted to disk { content }
"user_info" userInfo: true User-scoped preferences across agents { value, description? }
"workspace" sharedWorkspace: true Multi-agent coordination workspace { summary, content?, references?, status?, tags? }

When to Use Each Store

Need Store Why
Large data, external retrieval "notes" Index in context, full data via store_get
Small live state, instant access "whiteboard" Full values rendered directly in context
Cross-session agent rules "instructions" Persists to disk, auto-loaded on start
User preferences shared across agents "user_info" User-scoped, not agent-scoped
Multi-agent data sharing "workspace" Versioned entries with author tracking

Migration from Old Tool Names

Old Tool New Equivalent
memory_store(key, desc, value, ...) store_set("notes", key, { description, value, tier?, ... })
memory_retrieve(key) store_get("notes", key)
memory_delete(key) store_delete("notes", key)
memory_query(...) store_action("notes", "query", { pattern?, tier?, ... })
memory_cleanup_raw() store_action("notes", "cleanup_raw")
context_set(key, desc, value, ...) store_set("whiteboard", key, { description, value, priority? })
context_delete(key) store_delete("whiteboard", key)
context_list() store_list("whiteboard")
instructions_set(key, content) store_set("instructions", key, { content })
instructions_remove(key) store_delete("instructions", key)
instructions_list() store_list("instructions")
instructions_clear(confirm) store_action("instructions", "clear", { confirm: true })
user_info_set(key, value, desc?) store_set("user_info", key, { value, description? })
user_info_get(key?) store_get("user_info", key?)
user_info_remove(key) store_delete("user_info", key)
user_info_clear(confirm) store_action("user_info", "clear", { confirm: true })

Note: TODO tools (todo_add, todo_update, todo_remove) are unchanged.

Example Usage by Store

Memory Store

jsonc
// Store data in working memory
// Tool call from LLM:
{
  "name": "store_set",
  "arguments": {
    "store": "notes",
    "key": "api_response",
    "data": {
      "description": "Full API response from /users endpoint",
      "value": { "users": ["Alice", "Bob", "Charlie"] },
      "tier": "findings",
      "priority": "high"
    }
  }
}

// Retrieve data
{
  "name": "store_get",
  "arguments": {
    "store": "notes",
    "key": "api_response"
  }
}

// Query memory entries
{
  "name": "store_action",
  "arguments": {
    "store": "notes",
    "action": "query",
    "params": { "tier": "findings", "pattern": "api_*" }
  }
}

// Clean up raw tier
{
  "name": "store_action",
  "arguments": {
    "store": "notes",
    "action": "cleanup_raw"
  }
}

Context Store

jsonc
// Store live state visible directly in context
{
  "name": "store_set",
  "arguments": {
    "store": "whiteboard",
    "key": "current_state",
    "data": {
      "description": "Processing state for current task",
      "value": { "step": 3, "status": "active" },
      "priority": "high"
    }
  }
}

// Delete an entry
{
  "name": "store_delete",
  "arguments": {
    "store": "whiteboard",
    "key": "temp_data"
  }
}

// List all entries
{
  "name": "store_list",
  "arguments": {
    "store": "whiteboard"
  }
}

Instructions Store

jsonc
// Set a persistent instruction
{
  "name": "store_set",
  "arguments": {
    "store": "instructions",
    "key": "personality",
    "data": {
      "content": "Always be friendly and helpful. Use clear, simple language."
    }
  }
}

// Remove an instruction
{
  "name": "store_delete",
  "arguments": {
    "store": "instructions",
    "key": "personality"
  }
}

// Clear all instructions
{
  "name": "store_action",
  "arguments": {
    "store": "instructions",
    "action": "clear",
    "params": { "confirm": true }
  }
}

User Info Store

jsonc
// Store user preference
{
  "name": "store_set",
  "arguments": {
    "store": "user_info",
    "key": "theme",
    "data": {
      "value": "dark",
      "description": "User preferred theme"
    }
  }
}

// Get all user info
{
  "name": "store_get",
  "arguments": {
    "store": "user_info"
  }
}

// Clear all user info
{
  "name": "store_action",
  "arguments": {
    "store": "user_info",
    "action": "clear",
    "params": { "confirm": true }
  }
}

Creating a Custom Store Plugin

Any plugin that implements IContextPluginNextGen and IStoreHandler automatically becomes available as a store target. The IStoreHandler interface defines the CRUD operations:

typescript
// Documentation check: complete example
import {
  BasePluginNextGen,
  type IStoreHandler,
  type StoreEntrySchema,
  type StoreGetResult,
  type StoreSetResult,
  type StoreDeleteResult,
  type StoreListResult,
  type StoreActionResult,
} from 'oneringai';

class SnippetsPlugin extends BasePluginNextGen implements IStoreHandler {
  readonly name = 'snippets';

  private snippets = new Map<string, { text: string; createdAt: number }>();

  getStoreSchema(): StoreEntrySchema {
    return {
      storeId: 'snippets',
      displayName: 'Snippets',
      description: 'Text snippets keyed by name',
      usageHint: 'Use for: quick reusable text snippets.',
      setDataFields: 'text (required): Snippet content',
    };
  }

  // IStoreHandler implementation
  async storeGet(key?: string): Promise<StoreGetResult> {
    if (key) {
      const snippet = this.snippets.get(key);
      return snippet ? { found: true, key, entry: snippet } : { found: false, key };
    }
    // For this custom snippets store only, return all entries when key is omitted
    const entries = Array.from(this.snippets.entries()).map(([k, v]) => ({ key: k, ...v }));
    return { found: true, entries };
  }

  async storeSet(key: string, data: Record<string, unknown>): Promise<StoreSetResult> {
    const text = data.text as string;
    if (!text) return { success: false, key, error: 'Missing "text" field' };
    this.snippets.set(key, { text, createdAt: Date.now() });
    return { success: true, key, message: `Snippet "${key}" saved` };
  }

  async storeDelete(key: string): Promise<StoreDeleteResult> {
    const deleted = this.snippets.delete(key);
    return { deleted, key };
  }

  async storeList(filter?: Record<string, unknown>): Promise<StoreListResult> {
    const entries = Array.from(this.snippets.entries()).map(([k, v]) => ({
      key: k,
      text: v.text,
      createdAt: v.createdAt,
    }));
    return { entries, total: entries.length };
  }

  async storeAction(action: string, params?: Record<string, unknown>): Promise<StoreActionResult> {
    if (action === 'clear') {
      if (!params?.confirm) return { success: false, action, error: 'Requires confirm: true' };
      this.snippets.clear();
      return { success: true, action, message: 'All snippets cleared' };
    }
    return { success: false, action, error: `Unknown action: ${action}` };
  }

  // Standard plugin methods
  getInstructions(): string | null { return 'Use store_set("snippets", key, { text }) to save text snippets.'; }
  async getContent(): Promise<string | null> { return null; }
  getContents(): unknown { return Object.fromEntries(this.snippets); }
  getTools() { return []; }  // No plugin-specific tools needed; store_* tools handle everything
}

Register and use:

typescript
const ctx = AgentContextNextGen.create({ model: 'gpt-4.1' });
ctx.registerPlugin(new SnippetsPlugin());

// Now the LLM can use:
// store_set("snippets", "meeting", { text: "Discussed Q3 roadmap" })
// store_get("snippets", "meeting")
// store_list("snippets")
// store_action("snippets", "clear", { confirm: true })

Documentation snapshot · 2026-11-02Suggest a correction ↗

Search documentation

Type to search the v2 documentation.