Skip to content

feat: implement EDA long-term memory plugin and upgrade plugin system infrastructure#1870

Open
xiaobin83 wants to merge 17 commits into
moeru-ai:mainfrom
xiaobin83:feat/openviking-memory-plugin
Open

feat: implement EDA long-term memory plugin and upgrade plugin system infrastructure#1870
xiaobin83 wants to merge 17 commits into
moeru-ai:mainfrom
xiaobin83:feat/openviking-memory-plugin

Conversation

@xiaobin83
Copy link
Copy Markdown

@xiaobin83 xiaobin83 commented May 24, 2026

Description

This PR adds the openviking-memory EDA (Event-Driven Architecture) long-term memory plugin, and supplements & optimizes the project-wide plugin system infrastructure.

Core changes are as follows:

  • stage-tamagotchi: Implemented PluginHost config system with schema validation, Eventa IPC, settings UI and i18n; redesigned plugin config UX with dirty tracking; fixed plugin tool timing and config application bugs.

  • plugin-sdk: Extended plugin-tools with memory context injection and post-processing hooks.

  • stage-ui: Registered plugin context provider for chat orchestrator to support plugin capability docking.

  • openviking-memory: Implemented complete memory CRUD capabilities based on PluginHost SDK, sorted out plugin code structure, and added supporting build pipeline.

Additional Context

Please focus on the main project code modifications (stage-tamagotchi / plugin-sdk / stage-ui) during review, including plugin host configuration logic, SDK hook extension, chat orchestrator context registration and related bug fixes, to verify main process stability and capability compatibility.

Known Issues

  • The is only Chinese README.zh-CN.md in openviking-memory folder.

Coming soon

  • Character isolated memory
  • Account isolated memory
  • A proper plugin installer (by drag-n-drop)

Screenshots

Notice, the first two screenshots were captured from development mode. The last one was captured from app.

Open a new chat,
截屏2026-05-24 18 59 36

Reset the chat,
截屏2026-05-24 19 00 10

Restart the app,
截屏2026-05-24 19 30 19

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1215d52ef2

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/stage-tamagotchi/src/main/services/airi/plugins/host/index.ts Outdated
Comment thread apps/stage-tamagotchi/src/renderer/stores/plugin-tools.ts Outdated
Comment thread apps/stage-tamagotchi/src/renderer/stores/plugin-tools.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f554c1bdbe

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/stage-tamagotchi/src/main/services/airi/plugins/host/config.ts Outdated
Comment thread apps/stage-tamagotchi/src/main/services/airi/plugins/host/index.ts
@xiaobin83
Copy link
Copy Markdown
Author

xiaobin83 commented May 24, 2026

update:
the implementation has been changed to use runtimeContextProviders.


I noticed there is runtimeContextProviders added in chat-orchestrator-runtime.ts 5 days ago, which can be used for my injectMemoryContext, I'll change the implementation. I was using onBeforeCompose (added just in the place of runtimeContextProviders).

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d67784f9fb

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/stage-tamagotchi/src/renderer/stores/plugin-tools.ts Outdated
Comment thread apps/stage-tamagotchi/src/renderer/stores/plugin-tools.ts Outdated
Comment thread apps/stage-tamagotchi/src/renderer/stores/plugin-tools.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2c59f1d806

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/stage-tamagotchi/src/main/services/airi/plugins/host/index.ts Outdated
Comment thread apps/stage-tamagotchi/src/main/services/airi/plugins/host/index.ts Outdated
@xiaobin83 xiaobin83 force-pushed the feat/openviking-memory-plugin branch from 2c59f1d to 85dfcbf Compare May 25, 2026 15:53
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 85dfcbf5a0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/stage-tamagotchi/src/renderer/stores/plugin-tools.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ce5e8a78cd

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/stage-tamagotchi/src/renderer/stores/plugin-tools.ts Outdated
Comment thread apps/stage-tamagotchi/src/main/services/airi/plugins/host/index.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 13a96c1d8b

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/stage-tamagotchi/src/renderer/stores/plugin-tools.ts Outdated
@xiaobin83 xiaobin83 force-pushed the feat/openviking-memory-plugin branch from e367d49 to f046694 Compare May 25, 2026 18:40
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f046694358

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/stage-tamagotchi/src/main/services/airi/plugins/host/index.ts
xiaobin83 and others added 11 commits May 26, 2026 23:25
…onfig system, context hooks, and example plugin

- stage-tamagotchi: add PluginHost config system with schema validation, Eventa IPC, settings UI, and i18n

- plugin-sdk: extend plugin-tools with injectMemoryContext and post-processing hooks

- stage-ui: add plugin context provider registration for chat orchestrator

- stage-tamagotchi: redesign plugin settings config UX with dirty tracking

- stage-tamagotchi: fix plugin tool timing and config apply workaround

- openviking-memory: add example plugin with memory CRUD via PluginHost SDK, reorganize source, and add build pipeline

- docs: update plugin host design documents
…ptions

Add config?: ModuleConfigEnvelope to PluginStartOptions for passing updated config to init

Fix PluginHost.init() to use options.config when calling applyConfiguration, instead of always passing an empty envelope

Update loadPluginByName in stage-tamagotchi host to accept and forward config to host.start

Let loadEnabledPlugins build a config envelope from the already-fetched config and pass it directly, avoiding a redundant getConfig() call

Let setPluginConfig pass the updated config envelope via host.reload() options so reloaded sessions receive the latest config
Reset conversationSessionId via useChatMaintenanceStore $onAction when cleanupMessages fires, so plugin memory saves start a fresh session.

- Fix save conversation not working across cleanup boundaries - Reimplement injectMemoryContext as runtime context provider
…rom chat session

- Wrap listPlugins() calls in injectMemoryContext and onChatTurnComplete
  with try-catch to soft-fail on transient errors
- Derive conversationSessionId from active chat session instead of a
  global ref; remove cleanupMessages workaround
- Remove noisy console.info logs from plugin-tools and openviking
…te on plugin config reload

Revoke prior asset sessions after host.reload triggered by setPluginConfig, preventing stale 30-day TTL asset URLs/cookies from accumulating.

Clear loaded state (loaded set + loadedSessionIds) and revoke asset sessions when host.reload throws, preventing inconsistent host state where a plugin appears loaded but holds a stale session id.

- clearModuleAssetSessionCacheByOwnerSessionId + revokeByOwnerSessionId called after successful host.reload for the old session

- On reload failure, loaded/loadedSessionIds are cleaned up and old asset sessions revoked before re-throwing the error
…rt it

Filter `memory_save_conversation` invocation to only plugins that actually register the tool, eliminating warning noise and unnecessary IPC work on every chat turn.

- Extract 'memory_save_conversation' string into MEMORY_SAVE_CONVERSATION_TOOL constant

- Cache plugin IDs that expose this tool during refresh() from xsai tool definitions

- Filter loaded+enabled plugins in registerPostProcessingHook against the cache

- Clear the cache in dispose()
…ect memory_search tool invocation

Remove the intermediate queryContext Eventa IPC pathway and the associated contract definition file

Replace indirect queryContext calls with direct invokePluginTool calls to the memory_search tool in the renderer store

Add limit parameter support to searchMemories API with default value

Split pluginsWithMemoryTool into separate pluginsWithMemorySaveTool and pluginsWithMemorySearchTool sets for clearer responsibility

Clean up stale mocks and imports in tests
…posing sends

The chat send path blocked on plugin context lookup because performSend awaits runtime context providers, and injectMemoryContext invoked invokePluginTool sequentially for each loaded plugin. When the OpenViking backend is down, memory_search could take ~30s+ per plugin due to retry+timeout, freezing user sends before any token streams.

Changes: - Replace sequential for-loop with concurrent Promise.allSettled - Add AbortSignal.timeout(3_000) per plugin invoke to fail fast - Each slow/timed-out plugin is silently skipped with a warning - Maximum total wait is bounded to 3s regardless of plugin count
- Add required field validation: reject missing or empty required fields
- Add value type validation: enforce string/secret/number/boolean per schema
- Preserve existing unknown key rejection with stricter type assertion
- Add comprehensive unit test suite (13 test cases covering all validation paths)
…d cleanup in setPluginConfig

- Split single try/catch into two: one for host.reload() failures,
  another for post-reload asset cookie revocation
- Log cleanup errors instead of clearing host bookkeeping when
  reload succeeded but asset revocation fails
- Prevents host bookkeeping inconsistency where a running session is
  marked as unloaded due to non-fatal cleanup errors
…atTurnComplete to prevent misattribution

- Change ensureConversationSessionId signature to require (sessionId, generation) parameters so callers must provide captured metadata
- Move sessionId/generation capture before the await listPlugins() call in onChatTurnComplete callback to lock the originating session synchronously
- This ensures that a concurrent session switch during streaming does not persist the completed turn under the wrong session ID in long-term memory
@xiaobin83 xiaobin83 force-pushed the feat/openviking-memory-plugin branch from 85ed762 to d2b515e Compare May 26, 2026 15:25
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d2b515e307

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/stage-tamagotchi/src/renderer/stores/plugin-tools.ts Outdated
Comment thread apps/stage-tamagotchi/src/main/services/airi/plugins/host/index.ts Outdated
xiaobin83 added 2 commits May 26, 2026 23:38
…ation

Replace generic Error with TypeError in host plugin config validation for more precise error semantics when type mismatches occur.

- Config field string type validation

- Config field number type validation

- Config field boolean type validation
… in plugin config validation

The required-field guard in setPluginConfig only rejected empty strings for type === 'string', but skipped the same check for type === 'secret'. This allowed a schema field marked { required: true, type: 'secret' } to be saved as '', persisted, and reloaded as an unusable credential.

- Extended the empty-value check to cover both 'string' and 'secret' types

- Made the error message dynamic to reflect the actual field type
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 93d7f73985

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/stage-tamagotchi/src/renderer/pages/settings/plugins/index.vue Outdated
Comment thread apps/stage-tamagotchi/src/renderer/pages/settings/plugins/index.vue Outdated
Eliminate a race condition in plugin-tools where a concurrent session switch during streaming could misattribute a completed turn to the wrong session. The sessionId and generation are now carried inside ChatStreamEventContext instead of read from the session store at async handler time.

- Add sessionId and generation fields to ChatStreamEventContext so downstream consumers identify the originating session without external store state

- Persist generation counter in ChatSessionMeta so it survives reloads; ensureGeneration and loadIndexForUser restore from persisted value

- Remove useChatSessionStore dependency from plugin-tools store; read sessionId and generation from the event context instead
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 34c9e9ae56

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread packages/stage-ui/src/stores/chat/session-store.ts Outdated
…er inputs in plugin settings

Preserve unsaved config edits when plugin list refreshes instead of resetting all editors; merge existing editor states and only add/remove entries for new/stale plugins

Reject invalid number input in saveConfig with an inline error message instead of silently omitting the value from the saved config

Reload only the saved plugin's config after savePluginConfig instead of reloading all configs, preventing the refresh from discarding unsaved edits in other plugin forms

Remove now-unused loadAllConfigs helper
xiaobin83 added 2 commits May 27, 2026 01:41
applyRemoteSnapshot previously kept the local generation when already initialized, causing follower windows to retain stale generation values after another window resets a chat. Since memory session IDs include the generation, subsequent turns in the follower would be persisted under the pre-reset namespace, mixing old and new memory history.

- Remove fallback to sessionGenerations.value[sessionId] when applying remote snapshot

- Always trust snapshot.sessionMetas[sessionId]?.generation for each session in the incoming snapshot
The refactor-remote-plugins-to-plugin-host planning document has served its purpose — M1-M3 are completed and the core migration is done. Removing it to keep the .trae/documents directory clean.
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.

2 participants