OpenAI Integration

Add persistent memory to GPT-4o or any OpenAI model. Works with both the Chat Completions API and the Assistants API.

Install

pip install openai requests

Agent loop with persistent memory

from openai import OpenAI
import requests

SYNAPSE_KEY = "sk_syn_your_key_here"
SYNAPSE_URL = "https://synapse.by-kit.com/api/v1"
AGENT_ID = "gpt-assistant"

openai_client = OpenAI(api_key="sk-...")


def synapse_write(title: str, body: str, memory_type: str = "exchange"):
    """Persist a memory to Synapse."""
    requests.post(
        f"{SYNAPSE_URL}/record",
        headers={"Authorization": f"Bearer {SYNAPSE_KEY}"},
        json={
            "agent_id": AGENT_ID,
            "type": memory_type,
            "title": title,
            "body": body
        }
    )


def synapse_query(query: str, limit: int = 5) -> list[dict]:
    """Retrieve relevant memories."""
    resp = requests.get(
        f"{SYNAPSE_URL}/query",
        headers={"Authorization": f"Bearer {SYNAPSE_KEY}"},
        params={"q": query, "agent_id": AGENT_ID, "limit": limit}
    )
    return resp.json() if resp.ok else []


def build_context_messages(query: str) -> list[dict]:
    """Convert Synapse memories to OpenAI message format."""
    memories = synapse_query(query)
    if not memories:
        return []
    context_text = "\n".join(
        f"[{m['type']}] {m['title']}: {m['body']}"
        for m in memories
    )
    return [{
        "role": "system",
        "content": f"Relevant context from previous sessions:\n{context_text}"
    }]


def chat(user_message: str, conversation_history: list[dict] = None) -> str:
    history = conversation_history or []

    # Build messages: system + context + history + user message
    messages = [
        {"role": "system", "content": "You are a helpful assistant with persistent memory."},
        *build_context_messages(user_message),
        *history,
        {"role": "user", "content": user_message}
    ]

    response = openai_client.chat.completions.create(
        model="gpt-4o",
        messages=messages
    )

    reply = response.choices[0].message.content

    # Persist the exchange
    synapse_write(
        title=f"Q: {user_message[:80]}",
        body=f"User: {user_message}\nAssistant: {reply}",
        memory_type="exchange"
    )

    return reply


# Assistants API integration — use Synapse for cross-thread memory
def assistant_with_memory(thread_id: str, user_message: str) -> str:
    """Add cross-thread context before running an Assistant."""
    memories = synapse_query(user_message)
    context = "\n".join(f"[{m['type']}] {m['title']}: {m['body']}" for m in memories)

    # Add context as a system message in the thread
    if context:
        openai_client.beta.threads.messages.create(
            thread_id=thread_id,
            role="user",
            content=f"[Context from memory]\n{context}\n\n[Current message]\n{user_message}"
        )
    else:
        openai_client.beta.threads.messages.create(
            thread_id=thread_id,
            role="user",
            content=user_message
        )

    return thread_id

Tips

  • For Assistants API: use Synapse as the cross-thread memory layer. OpenAI thread context is per-thread; Synapse context is global to your agent.
  • Write decisions and facts explicitly — don't rely on summarization. Specific records surface better in queries.
  • Use agent_id per user for multi-user apps — each user gets their own isolated memory namespace.
  • For function-calling agents: expose synapse_write and synapse_query as tools so the model can manage its own memory.