How the Blueprint-Sessions System Creates and Applies Session Templates in OpenWork

The blueprint-sessions system in OpenWork creates session templates by normalizing raw JSON configuration into typed objects via normalizeBlueprintSessionTemplates, and applies them by sanitizing stale data and injecting fresh materialized sessions through applyMaterializedBlueprintSessions.

The blueprint-sessions subsystem powers template-based session management in the different-ai/openwork repository. Located in apps/server/src/blueprint-sessions.ts, this system bridges raw configuration files and the UI by converting blueprint definitions into concrete, interactive sessions. Understanding this flow is essential for extending OpenWork's templating capabilities or debugging session initialization issues.

Creating Session Templates from Raw Configuration

The creation process transforms untyped JSON into validated BlueprintSessionTemplate objects through defensive normalization.

Extracting the Blueprint Block

The entry point normalizeBlueprintSessionTemplates first extracts the blueprint object from the overall OpenWork configuration using readRecord(openwork?.blueprint). It then iterates over the sessions array, safely converting each raw entry into a plain object with readRecord(value) and discarding malformed items that fail validation.

Normalizing Template Fields

Each session undergoes strict field normalization:

  • title – Trimmed to a string, defaulting to "Template session N" when missing or empty.
  • messages – Processed through normalizeMessage, which guarantees a valid role ("assistant" or "user") and ensures non-empty text content.
  • id – Uses the supplied identifier or auto-generates template-session-N based on array index.
  • openOnFirstLoad – Boolean flag copied verbatim when true.

The function filters out any null results, returning a clean array of typed templates ready for the frontend.

Reading Materialized Sessions

Once templates are instantiated into actual sessions, readMaterializedBlueprintSessions retrieves the concrete mappings. This function mirrors the creation pattern but operates on blueprint.materialized.sessions.items, returning plain objects containing {templateId, sessionId} pairs. It discards entries lacking required fields, ensuring the UI only receives valid session references.

Applying Materialized Sessions to Configuration

When persisting concrete sessions back to the configuration, the system follows a sanitization-first approach through applyMaterializedBlueprintSessions.

Sanitizing Stale Data

The function first calls sanitizeOpenworkTemplateConfig to clone the configuration object and delete any existing materialized.sessions data. This prevents stale template references from accumulating and ensures a clean slate for new materializations.

Injecting New Session Data

After sanitization, the system reads or creates the blueprint.materialized block and injects a new sessions object containing:

  • A hydratedAt timestamp marking the materialization time
  • A shallow copy of the supplied items array containing the template-to-session mappings

The modified openwork object now carries the freshly materialized sessions, ready for persistence or client transmission.

Code Examples

Creating Session Templates from Raw Config

import { normalizeBlueprintSessionTemplates } from "@/blueprint-sessions";

const rawOpenwork = {
  blueprint: {
    sessions: [
      { id: "welcome", title: "Welcome", messages: [{ role: "assistant", text: "Hi!" }] },
      { title: "Untitled", messages: [{ role: "user", text: "Hello" }] }
    ],
  },
};

const templates = normalizeBlueprintSessionTemplates(rawOpenwork);
// → [
//   { id: "welcome", title: "Welcome", messages: [{ role: "assistant", text: "Hi!" }], openOnFirstLoad: false },
//   { id: "template-session-1", title: "Untitled", messages: [{ role: "user", text: "Hello" }], openOnFirstLoad: false }
// ]

Applying Materialized Sessions

import { applyMaterializedBlueprintSessions } from "@/blueprint-sessions";

const materialised = [
  { templateId: "welcome", sessionId: "session-abc123" },
  { templateId: "template-session-1", sessionId: "session-def456" }
];

const updatedOpenwork = applyMaterializedBlueprintSessions(rawOpenwork, materialised, Date.now());
// updatedOpenwork.blueprint.materialized.sessions.hydratedAt contains the timestamp
// updatedOpenwork.blueprint.materialized.sessions.items contains the mappings

Reading Materialized Sessions Later

import { readMaterializedBlueprintSessions } from "@/blueprint-sessions";

const sessions = readMaterializedBlueprintSessions(updatedOpenwork);
// → [{ templateId: "welcome", sessionId: "session-abc123" }, …]

Summary

  • Normalization happens in normalizeBlueprintSessionTemplates located in apps/server/src/blueprint-sessions.ts, which validates and types raw JSON configuration.
  • Default values protect against malformed input, including auto-generated IDs and fallback titles for incomplete templates.
  • Materialization separates templates from instances, tracking concrete sessions through {templateId, sessionId} mappings in the materialized configuration block.
  • Sanitization prevents data corruption by cloning the config and removing stale session data before injecting new materializations.

Frequently Asked Questions

What happens when a session template lacks a title?

The normalization process assigns a default title formatted as "Template session N" where N represents the item's index in the sessions array. This ensures every template has a displayable identifier even when the raw configuration omits the title field.

How does the system handle invalid or malformed session entries?

During the normalizeBlueprintSessionTemplates execution, each raw entry passes through readRecord(value) for safe conversion. Entries that fail validation or return null are filtered out of the final array, preventing corrupt data from reaching the UI.

What is the difference between blueprint session templates and materialized sessions?

Blueprint session templates define the structure and initial content of reusable sessions, while materialized sessions represent concrete instances created from those templates. The system stores materialized sessions in blueprint.materialized.sessions.items as pairs of template IDs and generated session IDs, tracking when they were hydrated via the hydratedAt timestamp.

Where is the blueprint-sessions logic implemented in the OpenWork codebase?

The core implementation resides in apps/server/src/blueprint-sessions.ts, which exports the normalization, reading, and application functions. The server entry point in apps/server/src/server.ts consumes these utilities when serving workspace data, while apps/server/src/blueprint-sessions.test.ts contains the test suite guarding against regressions.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →