Skip to content

[OMEGA-248] Memory Backup and Restore - #329

Open
blackhammer116 wants to merge 34 commits into
singnet:mainfrom
iCog-Labs-Dev:dev/new-feature
Open

[OMEGA-248] Memory Backup and Restore#329
blackhammer116 wants to merge 34 commits into
singnet:mainfrom
iCog-Labs-Dev:dev/new-feature

Conversation

@blackhammer116

@blackhammer116 blackhammer116 commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Description

This PR adds operator-controlled memory backup and restore support to OmegaClaw Core while keeping archive processing inside the standalone import-kb package.
It supports:

  • Exporting conversation history, ChromaDB LTM records, or both.
  • Restoring archives during container startup.
  • overwrite and experimental append import modes.
  • Selective history/vector imports.
  • Embedding compatibility checks and re-embedding through the configured provider.
  • Docker-mounted transfer directories for accessing archives outside the container.

OmegaClaw Core now handles:

  • Launcher CLI options and validation.
  • Mounting the user-supplied transfer directory at /memory-transfer.
  • Starting an import before the agent loop.
  • Dispatching authenticated /memory-export commands.
  • Passing the active embedding provider to the portability package.
  • Reporting export results through supported communication channels.

Archive creation, validation, import, rollback, recovery, and ChromaDB record handling remain in the import-kb dependency.

Export flow

Start OmegaClaw with a host transfer directory:

scripts/omegaclaw start \
  --memory-transfer-dir "$HOME/omegaclaw-transfers" \
  --enable-memory-export \
  [other options]

Then request an export through a supported channel:

/memory-export history
/memory-export ltm
/memory-export both
/memory-export confirm <token>

The resulting .tar.gz archive is written to the mounted host directory. Export is disabled by default and is not supported through WebSocket chat.

Import flow

scripts/omegaclaw start \
  --memory-transfer-dir "$HOME/omegaclaw-transfers" \
  --memory-import omegaclaw-memory-<timestamp>.tar.gz \
  --memory-mode overwrite \
  [other options]

Optional component flags:

--only-history
--no-history
--no-vector

Before the agent starts, the entrypoint:

  1. Runs interrupted-import recovery.
  2. Validates and imports the requested archive.
  3. Re-embeds LTM records when the stored embedding profile is incompatible.
  4. Starts the agent only after a successful import.

Testing

Added coverage for:

  • Export enablement and confirmation.
  • Invalid, expired, and cross-owner tokens.
  • Synchronous export execution and result reporting.
  • Active embedding-provider propagation.
  • Shared channel control-command dispatch.
  • Explicit WebSocket unsupported behavior.

How Has This Been Tested?

  • By running the test coverages in the tests dir and manual verification.

Checklist

  • Does PR contain autogenerated code?
  • Is self-review completed?
  • Are test scenarios above passed with the version of the code from PR?

Bereket-Eshete and others added 23 commits August 18, 2026 12:27
Install import-kb v0.2.1 in the image and invoke its memory portability module during startup. This replaces the separate memory-portability package reference.
Queue confirmed export requests in channel handlers and process them before the next agent prompt. This keeps commands outside the LLM while making archive creation synchronous with normal memory writes.
Restore direct history and ChromaDB access now that exports run sequentially in the main loop. The gateway lock is no longer needed.
@vsbogd

vsbogd commented Aug 21, 2026

Copy link
Copy Markdown
Member

Please answer the usual PR questions:

  • Does PR contain autogenerated code?
  • Is self-review completed?
  • Are test scenarios above passed with the version of the code from PR?

Comment thread channels/irc.py Outdated
Comment thread src/memory_export.py
Comment thread docs/reference-memory-portability.md Outdated
Comment thread entrypoint.sh Outdated
Comment thread requirements.txt Outdated
Comment thread src/channels.py Outdated
Comment thread docs/reference-memory-portability.md Outdated
@blackhammer116

Copy link
Copy Markdown
Collaborator Author

@vsbogd

It adds complexity to the code but at the same time it doesn't mapped on the requirements (as far as I see). We already have authentication on the channel and command can be sent only by authenticated user. I don't see a reason for adding one more authentication mechanism. I suggest removing it.

Its more of a confirmation rather than an authentication.

@vsbogd

vsbogd commented Aug 24, 2026

Copy link
Copy Markdown
Member

Its more of a confirmation rather than an authentication.

I don't see any reason why confirmation is needed.

@vsbogd

vsbogd commented Aug 24, 2026

Copy link
Copy Markdown
Member

QA note: both Local and OpenAI embeddings exporting/importing cases should be tested.

@blackhammer116

Copy link
Copy Markdown
Collaborator Author

@vsbogd addressed the comments, enabled wsocket support, removed confirmation check, updated README with clear scope and limitation of memory-import

@vsbogd

vsbogd commented Aug 28, 2026

Copy link
Copy Markdown
Member

import-kb changes PR: singnet/import-knowledge-package#1

Comment thread src/memory_export.py Outdated
raise ValueError(f"Unsupported embedding provider: {embedding_provider!r}")

os.environ["EMBEDDING_PROVIDER"] = embedding_provider
_transfer = MemoryTransfer(_TRANSFER_DIR)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MemoryTransfer is instantiated without passing MemoryStore argument. In such case MemoryTransfer uses default MemoryStore instance which uses default memory_dir, chroma_db and collection values. This couples OmegaClaw code with library code. If memory dir or chroma db location are changed via settings or collection name is changed in "petta chroma db" library the import-kb should also be changed (see https://github.com/asi-alliance/import-knowledge-package/pull/1/changes#r3845201282). We need to instantiate MemoryStore here with passing all necessary paths to it. Otherwise if user changes memoryDirectory parameter the export doesn't work.

@vsbogd vsbogd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@blackhammer116 one comment left (https://github.com/asi-alliance/OmegaClaw-Core/pull/329/changes#r3880411652) and I think it is critical. Other than that looks good to me.

@TossSky

TossSky commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

Verified against acf9230 with an image built from this branch, real providers (Anthropic for the agent loop, real OpenAI key for embeddings), no mocks for the memory feature.

What I checked

  • Unit tests added by the change (tests/test_memory_export.py): 16 passed. Full tests/pytest.sh: 28 passed.
  • Export over an authenticated channel: /memory-export both, history, ltm, dispatched from src/channels.py into src/memory_export.py. Reported SHA-256 matches the archive on disk; every member size and checksum matches manifest.json.
  • Component selection: both = 2 records, history = 0, ltm = 2.
  • Overwrite import onto a fresh deployment: history and vector records restored, ids, documents and metadata identical to the export, agent loop continues and its own query retrieves the imported memories.
  • Append import onto an instance with existing memory: pre-existing marker kept, imported records added under rewritten ids with memory_import_id, no exception.
  • Import flags in scripts/omegaclaw: --only-history, --no-history, --no-vector.
  • Local and OpenAI embeddings, both cross-provider directions: OpenAI archive (3072) into a Local instance re-embeds to 1024, Local archive (1024) into an OpenAI instance to 3072. Ids and documents preserved, no dimension mismatch.
  • Repeat import of the same archive short-circuits on the stored receipt.
  • Plain start with no memory flags is unaffected by the new startup recovery stage in entrypoint.sh.

Findings

  • manifest.json records source.omegaclaw_version as "unknown" in every archive: archive_metadata() reads OMEGACLAW_VERSION, which is set nowhere, not in the Dockerfile and not in the SAFE_VARS allowlist. The runtime already knows its version, so it only needs wiring through.
  • --only-history and --no-vector set the same variable and produce identical results, down to the receipt filename. There is no --only-vector counterpart.

Verdict: PASS
@blackhammer116 @vsbogd

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants