Shelvia
RecipeAvailable

Recipe, OpenAI Agents SDK + Shelvia

Shelvia is the memory layer the Agents SDK calls, Shelvia does not run your agents. The Agents SDK runs them; Shelvia gives each run reviewed context and accepts new memory only through the review queue.

Principle

Treat Shelvia as a typed tool the Agents SDK can call. Reads use the memory.read or memory.context scope. Writes go through the memory.candidates scope and produce a pending review candidate, never a trusted memory row.

Setup

  • Create a Workspace API token in Settings > API with scopes: memory.read + memory.context (read-only run) OR + memory.candidates (run that proposes new memory).
  • Store the token in SHELVIA_API_KEY. Never log it.
  • Install the Shelvia SDK: npm install @shelvia/sdk

Pattern, Shelvia as a read tool

Register a Shelvia retrieval as one of the Agents SDK's typed tools. The agent calls it before generating; the response is a ranked context pack with structured sections.

import { Agent, tool } from "openai-agents-sdk";
import { ShelviaClient } from "@shelvia/sdk";

const shelvia = new ShelviaClient({ apiKey: process.env.SHELVIA_API_KEY! });

const fetchShelviaContext = tool({
  name: "fetch_shelvia_context",
  description:
    "Retrieve reviewed Shelvia project memory before acting. Returns decisions, sources, prompts, next steps, and constraints.",
  parameters: {
    project_id: { type: "string", description: "Shelvia project id" },
    purpose:    { type: "string", description: "Why this context is needed" },
  },
  execute: async ({ project_id, purpose }) => {
    const pack = await shelvia.context.generatePack(project_id, {
      purpose,
      max_chars: 12000,
      semantic_ranking: true,
    });
    return pack;
  },
});

const agent = new Agent({
  name: "release-coordinator",
  instructions:
    "Before answering, call fetch_shelvia_context to retrieve reviewed Shelvia memory. Cite decisions and sources by id when you use them.",
  tools: [fetchShelviaContext],
});

Pattern, agent proposes a memory candidate

When the agent run produces a new claim worth keeping, propose it as a candidate. It enters the review queue with status pending. A workspace member approves before it becomes trusted memory.

const proposeShelviaCandidate = tool({
  name: "propose_shelvia_candidate",
  description:
    "Propose a Shelvia memory candidate (decision / next_step / open_question / ...). The candidate enters the review queue. A human approves before it becomes trusted memory.",
  parameters: {
    project_id: { type: "string" },
    type: {
      type: "string",
      enum: ["decision","next_step","open_question","prompt","source","note"],
    },
    title:   { type: "string" },
    content: { type: "string" },
    source_url: { type: "string", nullable: true },
  },
  execute: async ({ project_id, type, title, content, source_url }) => {
    return await shelvia.memory.createCandidate(
      project_id,
      { type, title, content, source_url },
      { idempotencyKey: `agent-openai-${runId}-${type}-${hash(content)}` },
    );
  },
});

Propose memory candidates safely

Agents propose. Humans approve. Shelvia keeps the trusted memory. The candidate write is not a trusted-memory write; the row enters the review queue and only a workspace member can promote it.

  • Identity: create a narrow-scope Workspace API token per agent run (label it, e.g., "OpenAI support-agent recipe"). Reuse shv_live_<hex> with memory.candidates + memory.context, no special token type.
  • Idempotency: every candidate write should carry an Idempotency-Key shaped agent-<runtime>-<run-id>-<candidate-hash>. Agent reruns are common; idempotency keeps the review queue clean.
  • Runtime tag: record the runtime via the logContinuation emit (suggested_tool: "openai-agents-sdk"). The candidate body does not carry a runtime field, observability does.
  • Never write to trusted memory directly. Shelvia has no service-token path that bypasses review. There is no shelvia.projects.writeDecision().
  • Never log raw chain-of-thought. Keep the candidate body to the final claim, not the reasoning trace. Use the optional `reasoning` field for a short justification only.
  • Never include secrets or tokens in the candidate body. The validator rejects forbidden keys (cookie, authorization, session_token, api_key, ...) with a structured error code.
  • Agents must not approve their own memory. Approval is a UI action in the Shelvia review surface, performed by a workspace member with the right role.

Observability (optional)

After a run, the agent can log a continuation event that records which reviewed context was used and what the next step should be. This is an optional audit / observability emit, it does NOT become trusted memory and does NOT bypass review-before-save. Scope required: continuations.log.

// After the agent run completes:
await shelvia.projects.logContinuation(projectId, {
  next_best_action: "Draft customer reply for the v2 launch",
  why: "Agent used the Shelvia context pack to summarize prior decisions.",
  suggested_tool: "openai-agents-sdk",
  priority: "normal",
});

Safety notes

  • Shelvia is not running the agent. The Agents SDK is. Shelvia is the reviewed memory the agent retrieves and proposes back into.
  • The candidate write is always pending. A workspace member must approve before it appears in any future context pack.
  • The continuation log is audit-only. It does not write to trusted memory tables (project_decisions, source_links, saved_prompts).
  • Pass an Idempotency-Key header (or @shelvia/sdk idempotencyKey) on the write tool if you retry runs.
  • Don't put the API key in the system prompt. Keep it server-side.
  • memory.read excludes pending candidates by default. Pass include_pending: true only when the agent should see them, and label every pending row in your UI.

Where to go next

  • REST API reference, /docs/developers/api
  • TypeScript SDK reference, /docs/developers/sdk
  • Review-before-save concept, /docs/concepts/review-before-save
  • Context Packs concept, /docs/concepts/context-packs

For runnable code samples and the developer reference, see /developers. For the trust model in depth, see /security.