Skip to main content

A guarded local-model learning cycle with PostgreSQL/pgvector L2 and L3 memory

Project description

DreamCycle

CI License Python PostgreSQL

Turn local-model conversations into compounding intelligence

DreamCycle is the memory and guarded self-improvement layer for local AI. It helps a model remember useful interactions, retrieve them when they matter, turn reviewed experience into training data, challenge new adapters against a baseline, and promote only the candidates that earn their place.

In plain English: your local model gets a memory, a learning loop, and a quality control system without giving its data to a hosted AI platform.

Record -> Recall -> Review -> Train -> Evaluate -> Promote -> Roll back

DreamCycle was created by Kenny Jin for builders who want local AI to become more useful over time without turning production into an uncontrolled training experiment.

DreamCycle is an early 0.2.1 alpha. If memory-native, locally controlled AI is useful to you, try the five-minute demo and open an issue with the first rough edge you hit. That feedback will shape the next release.

Why DreamCycle Exists

Local models are private and flexible, but most of them wake up with amnesia. Conversation logs pile up, useful corrections disappear, and "fine-tune it" often means gambling on a dataset without a promotion gate.

DreamCycle turns that loose history into a Local Intelligence Flywheel:

  • Memory Fabric: PostgreSQL and pgvector store scoped L2 episodes and vector-searchable L3 knowledge.
  • Context Recall: relevant experience can return to the prompt without replacing the vendor's model runtime.
  • Human Review Gate: captured turns start unapproved. Training requires an explicit review decision.
  • Dream Dataset Forge: approved conversations become deterministic training and held-out evaluation sets without splitting one conversation across both.
  • Candidate Arena: a new adapter is measured against the baseline before it can become active.
  • Adapter Vault: accepted adapters are activated atomically, with a previous version retained for rollback.

Training completion is not treated as model improvement. A candidate has to pass the configured evidence gates first.

Three Ways DreamCycle Improves Model Behavior

DreamCycle is not only a fine-tuning script. It is a behavior-improvement layer that can help at three different depths:

  • Prompt Lift: retrieve mode injects the right memories into the next request, so a local or OpenAI-compatible model gets sharper context immediately.
  • Local Weight Lift: reviewed conversations become train/eval datasets for local LoRA adapters, with evaluation and rollback before anything becomes active.
  • Cloud Dataset Lift: reviewed, scoped, provenance-backed examples can be exported into provider-ready training datasets when a vendor wants to fine-tune a cloud model through that provider's official workflow.

That means DreamCycle can improve how a cloud model is used through better prompt context today, while keeping cloud weight updates explicit, provider-owned, and opt-in.

The Architecture, Without the Enterprise Jargon

DreamCycle sits beside an existing local-model application. It is not a new AI platform that forces everything to be rebuilt around it.

flowchart LR
    App["Your app or agent"]
    SDK["DreamCycle Python SDK"]
    Proxy["Chat Completions proxy"]
    Memory["L2 and L3 memory fabric"]
    PG[("PostgreSQL + pgvector")]
    Model["Your local model server"]
    Cycle["Guarded dream cycle"]
    Adapter["Promoted adapter"]

    App -->|"a few SDK calls"| SDK
    App -->|"change the base URL"| Proxy
    SDK --> Memory
    Proxy --> Memory
    Memory <--> PG
    Proxy --> Model
    Memory -->|"reviewed experience"| Cycle
    Cycle -->|"evaluate, then promote"| Adapter
    Adapter -.->|"loaded by your runtime"| Model

There are three ways in:

  1. Drop-in proxy: point a configurable OpenAI-compatible Chat Completions client at DreamCycle and keep the existing conversation code.
  2. Vendor SDK: add explicit Python calls for record, recall, review, deletion, cycle jobs, and adapter control.
  3. Embedded engine: import the memory and cycle classes directly and keep everything inside one Python process.

The deeper component map, request flow, memory model, cycle state machine, and failure boundaries are in ARCHITECTURE.md.

What Ships Today

  • Direct PostgreSQL/pgvector L2 episodic memory.
  • Cosine, Euclidean/L2, and inner-product retrieval.
  • L3 knowledge nodes, relationships, and L2 provenance.
  • Immutable API-key bindings for namespace and user isolation.
  • Atomic user/assistant turn capture.
  • Explicit review, approval, rejection, and deletion controls.
  • A synchronous Python vendor SDK.
  • An authenticated FastAPI sidecar.
  • Observe and retrieve modes for POST /v1/chat/completions.
  • Non-streaming and SSE streaming response capture.
  • Asynchronous dream-cycle jobs with truthful status reporting.
  • Optional local Transformers/PEFT LoRA training.
  • Baseline-versus-candidate perplexity evaluation.
  • Atomic adapter promotion and one-step rollback.
  • Reviewed train/eval JSONL artifacts that can be adapted to cloud fine-tuning workflows.
  • Protocols for custom trainers, evaluators, embedders, shadow tests, event sinks, and knowledge extractors.

DreamCycle has no JintellarCore runtime dependency, no hosted API requirement, and no cloud-model requirement. It improves cloud-model usage through memory and datasets, but it does not automatically call hosted fine-tuning APIs or mutate closed-provider weights.

What DreamCycle Is and Is Not

DreamCycle is:

  • a PostgreSQL/pgvector memory layer for local AI systems;
  • a review-gated dataset builder for model improvement;
  • a Python SDK, sidecar API, and OpenAI-compatible proxy add-on;
  • a local adapter training and promotion loop for teams that want one.

DreamCycle is not:

  • a replacement for Ollama, LM Studio, llama.cpp, or a model server;
  • a hosted AI service;
  • a LangChain-style agent framework;
  • an automatic cloud fine-tuning client;
  • a promise that every remembered conversation should become training data.

Quick Start

Five-minute memory demo

This path does not need a downloaded embedding model or a local LLM. It starts PostgreSQL with pgvector, records one turn, recalls it, reviews it for training, promotes an L3 knowledge node, and prints the resulting training candidate.

git clone https://github.com/kenjix217/dreamcycle.git
cd dreamcycle

docker compose run --rm quickstart

The demo compose file keeps PostgreSQL inside Docker's private network, so it does not collide with an existing local Postgres server on 5432.

Install the mode you need

Core memory and orchestration:

pip install dreamcycle

Python vendor SDK:

pip install 'dreamcycle[sdk]'

Sidecar with local embeddings:

pip install 'dreamcycle[server,embeddings]'

Sidecar with local LoRA training:

pip install 'dreamcycle[server,embeddings,training]'

Start the sidecar

DreamCycle needs PostgreSQL with the pgvector extension enabled.

export DREAMCYCLE_POSTGRES_DSN='postgresql://dreamcycle:password@127.0.0.1/dreamcycle'
export DREAMCYCLE_EMBEDDING_MODEL='/models/all-MiniLM-L6-v2'
export DREAMCYCLE_API_KEY='replace-with-a-random-sidecar-key'
export DREAMCYCLE_NAMESPACE='my-local-model'
export DREAMCYCLE_USER_ID='local-user'

dreamcycle-server

The default bind is 127.0.0.1:8765. Interactive API documentation appears at http://127.0.0.1:8765/docs.

Add memory with the SDK

from dreamcycle.sdk import DreamCycleClient

with DreamCycleClient("http://127.0.0.1:8765", "sidecar-key") as client:
    user, assistant = client.record_turn(
        "How should retries be bounded?",
        "Use exponential backoff with a maximum attempt count.",
        conversation_id="conversation-42",
    )

    related = client.recall("retry strategy", limit=5)

    # Captured data cannot train anything until someone makes this decision.
    client.review(assistant.id, approved_for_training=True)

API keys are bound server-side to an immutable namespace and user ID. Request bodies cannot jump to a different memory scope.

Add Memory Without Rewriting the Vendor Platform

If the application already supports an OpenAI-compatible Chat Completions base URL, point it at:

Base URL: http://127.0.0.1:8765/v1
API key:  your DREAMCYCLE_API_KEY value

Then tell DreamCycle where the existing local model server lives:

export DREAMCYCLE_UPSTREAM_BASE_URL='http://127.0.0.1:11434/v1'
export DREAMCYCLE_PROXY_MODE='observe'
dreamcycle-server
  • Observe mode forwards the request and records completed turns.
  • Retrieve mode recalls scoped memory, labels it as untrusted historical reference data, and adds it before local inference.
export DREAMCYCLE_PROXY_MODE='retrieve'

The sidecar credential is never forwarded upstream. A different DREAMCYCLE_UPSTREAM_API_KEY can be configured when the local model server requires one.

This drop-in path applies to configurable Chat Completions clients. DreamCycle does not claim compatibility with the full OpenAI API or the Responses API.

See docs/VENDOR_SDK.md for every route, environment variable, streaming rule, identity option, and deployment boundary.

Use DreamCycle Directly in Python

import os

from dreamcycle.memory import PostgresMemory, PostgresMemoryConfig
from dreamcycle.memory import SentenceTransformerEmbedding

embeddings = SentenceTransformerEmbedding("/models/all-MiniLM-L6-v2")
memory = PostgresMemory(
    PostgresMemoryConfig(
        dsn=os.environ["DREAMCYCLE_POSTGRES_DSN"],
        namespace="my-local-model",
        user_id="developer-1",
        embedding_dimension=embeddings.dimension,
    ),
    embeddings,
)
memory.setup()

user_memory, assistant_memory = memory.remember_turn(
    "How should retries be bounded?",
    "Use exponential backoff with a maximum attempt count.",
    conversation_id="conversation-42",
)

similar = memory.recall("retry strategy", limit=5)
memory.mark_reviewed(assistant_memory.id, approved_for_training=True)

Set create_vector_extension=True only when the database role is allowed to run CREATE EXTENSION. Otherwise, enable pgvector as an operator before starting DreamCycle.

Build Durable L3 Knowledge

L3 is a vector-searchable PostgreSQL knowledge graph with provenance back to the original L2 memories.

practice = memory.promote_to_l3(
    [user_memory.id, assistant_memory.id],
    node_type="engineering-practice",
    key="bounded-retries",
    content="Retries use exponential backoff and a maximum attempt count.",
    confidence=0.95,
)

python = memory.upsert_knowledge(
    node_type="language",
    key="python",
    content="Python application development",
)

memory.link_knowledge(practice.id, python.id, "applies-to")
knowledge = memory.recall_knowledge("resilient Python calls")

Automatic knowledge extractors must retain valid L2 source IDs. DreamCycle rejects claims that cite memories outside the authenticated scope.

Run the Guarded Dream Cycle

Enable the built-in local training path:

export DREAMCYCLE_BASE_MODEL='/models/hf/my-local-model'
export DREAMCYCLE_DATA_DIR='/var/lib/dreamcycle'

Then start a cycle through the SDK:

job = client.start_cycle()
current = client.cycle_status(job.id)
print(current.status)

The HTTP job states are queued, running, completed, and failed. A 202 Accepted response means the cycle was queued; it does not mean training succeeded or the candidate was promoted.

The built-in evaluator compares candidate and baseline perplexity on held-out data. Coding, classification, tool-use, and domain products should plug in an evaluator that measures their real target behavior.

Bring Your Own Model Stack

DreamCycle is built around ordinary Python protocols, not one training vendor.

class MyTrainer:
    async def train(self, dataset_path, eval_path, output_path): ...


class MyEvaluator:
    async def evaluate(self, adapter_path, eval_path): ...

Return TrainingResult and EvaluationResult from dreamcycle. This leaves room for MLX, Unsloth, llama.cpp adapter pipelines, custom PyTorch code, and other local training stacks without pulling those frameworks into the core.

Cloud Models Without Cloud Lock-In

DreamCycle can sit in front of any OpenAI-compatible endpoint. In retrieve mode, the model receives a bounded memory packet as context, which can make hosted or local responses more consistent without changing the underlying model.

For actual cloud fine-tuning, DreamCycle should be treated as the dataset and governance layer. It records turns, keeps review decisions, preserves source provenance, and can feed approved examples into whatever fine-tuning workflow a provider officially supports. The hosted provider still owns upload, training, deployment, billing, and model-version policy.

Safety Is Part of the Product

  • Captured turns start unreviewed and unapproved.
  • Every memory query includes namespace and user scope.
  • SQL values use bound parameters and schema identifiers are validated.
  • L3 edges and provenance enforce scope with composite foreign keys.
  • Local model paths are the default; remote model download is opt-in.
  • Failed data preparation, training, evaluation, or promotion cannot become a fake success report.
  • A failed memory lookup does not discard an otherwise successful proxied model response.
  • Interrupted streams are not stored as completed assistant turns.
  • Adapter promotion uses an atomic pointer and preserves a rollback target.

Applications still own consent, retention, deletion, database security, model licensing, and the right to train on collected data.

Project Status and Roadmap

DreamCycle is ready for local evaluation as an alpha project. The most useful next community contributions are:

  • adapters and examples for popular local model servers;
  • task-specific quality evaluators;
  • an asynchronous vendor SDK;
  • durable distributed cycle jobs;
  • more embedding and training backends;
  • real-world compatibility reports.

Read the reviewed implementation baseline in docs/VENDOR_SDK_IMPLEMENTATION_REVIEW.md.

Development

git clone https://github.com/kenjix217/dreamcycle.git
cd dreamcycle
python3 -m venv .venv
.venv/bin/python -m pip install -e '.[dev]'

.venv/bin/python -m pytest
.venv/bin/python -m ruff check .
.venv/bin/python -m build
.venv/bin/python -m twine check dist/*

Set DREAMCYCLE_TEST_DSN to run the PostgreSQL integration tests. They create and remove uniquely named schemas.

Origin

DreamCycle was extracted and rewritten from Dream Engine work originally developed by Kenny Jin. The standalone project removes all JintellarCore runtime dependencies and connects directly to PostgreSQL.

License

Copyright 2026 Kenny Jin.

Licensed under the Apache License 2.0. See LICENSE and NOTICE. Direct dependency licenses are summarized in THIRD_PARTY.md.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dreamcycle-0.2.1.tar.gz (87.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dreamcycle-0.2.1-py3-none-any.whl (57.2 kB view details)

Uploaded Python 3

File details

Details for the file dreamcycle-0.2.1.tar.gz.

File metadata

  • Download URL: dreamcycle-0.2.1.tar.gz
  • Upload date:
  • Size: 87.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dreamcycle-0.2.1.tar.gz
Algorithm Hash digest
SHA256 6df91d14082c16696e3fd1db2272803ba1a3f8a356e398124e4015d8602210aa
MD5 33fb96c67640781f29c2061c6d34c42a
BLAKE2b-256 aa79a7cb1833130a32ba563322588180ce4511051b02edffb180d47f23c97ef7

See more details on using hashes here.

Provenance

The following attestation bundles were made for dreamcycle-0.2.1.tar.gz:

Publisher: ci.yml on kenjix217/dreamcycle

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dreamcycle-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: dreamcycle-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 57.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for dreamcycle-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b64c7563262d94788a4a2c51e8ae17db384092c7fb77bc3cb450b67e717ebbf0
MD5 b9d732f34b4f158989c361b47b163fa3
BLAKE2b-256 f2cc1100864801c0d8b2bf7fbae5bb68abd82f825f21d8f1b84c70bdc3d7e828

See more details on using hashes here.

Provenance

The following attestation bundles were made for dreamcycle-0.2.1-py3-none-any.whl:

Publisher: ci.yml on kenjix217/dreamcycle

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page