mirror of
https://github.com/dtzp555-max/memory-continuity.git
synced 2026-07-21 21:15:07 +00:00
fix: use _ctx.workspaceDir and strip channel metadata
- Hook callbacks now get workspace from _ctx.workspaceDir (the hook
context parameter) instead of api.runtime.workspaceDir which is
undefined in gateway mode. This was the root cause of the plugin
silently doing nothing on all remote/gateway deployments.
- extractStateFromMessages now strips Telegram/Discord channel
metadata ("Conversation info (untrusted metadata)") from user
messages before saving to CURRENT_STATE.md, preventing garbage
data in the Objective field.
Tested on: macOS local (GPT-5.4), Oracle Cloud (MiniMax M2.5)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -106,7 +106,14 @@ function extractStateFromMessages(messages) {
|
|||||||
? msg.content.filter(b => b?.type === "text").map(b => b.text).join("\n")
|
? msg.content.filter(b => b?.type === "text").map(b => b.text).join("\n")
|
||||||
: null;
|
: null;
|
||||||
if (!content) continue;
|
if (!content) continue;
|
||||||
if (role === "user") userMessages.push(content);
|
// Strip channel metadata (Telegram, Discord, etc.) from user messages
|
||||||
|
const cleaned = role === "user"
|
||||||
|
? content
|
||||||
|
.replace(/^Conversation info \(untrusted metadata\):[\s\S]*?\n\n/m, "")
|
||||||
|
.replace(/^Sender \(untrusted metadata\):[\s\S]*?\n\n/m, "")
|
||||||
|
.trim()
|
||||||
|
: content;
|
||||||
|
if (role === "user" && cleaned) userMessages.push(cleaned);
|
||||||
if (role === "assistant") assistantMessages.push(content);
|
if (role === "assistant") assistantMessages.push(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,14 +159,13 @@ const plugin = {
|
|||||||
|
|
||||||
register(api) {
|
register(api) {
|
||||||
const log = api.logger || console;
|
const log = api.logger || console;
|
||||||
const getWorkspace = () => api.runtime?.workspaceDir;
|
|
||||||
const getConfig = () => api.pluginConfig || {};
|
const getConfig = () => api.pluginConfig || {};
|
||||||
|
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
// HOOK 1: before_agent_start — inject recovered state into context
|
// HOOK 1: before_agent_start — inject recovered state into context
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
api.on("before_agent_start", async (_event, _ctx) => {
|
api.on("before_agent_start", async (_event, _ctx) => {
|
||||||
const ws = getWorkspace();
|
const ws = _ctx?.workspaceDir;
|
||||||
const statePath = resolveStatePath(ws);
|
const statePath = resolveStatePath(ws);
|
||||||
if (!statePath) return;
|
if (!statePath) return;
|
||||||
|
|
||||||
@@ -184,7 +190,7 @@ const plugin = {
|
|||||||
// HOOK 2: before_compaction — inject state so it survives compaction
|
// HOOK 2: before_compaction — inject state so it survives compaction
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
api.on("before_compaction", async (_event, _ctx) => {
|
api.on("before_compaction", async (_event, _ctx) => {
|
||||||
const ws = getWorkspace();
|
const ws = _ctx?.workspaceDir;
|
||||||
const statePath = resolveStatePath(ws);
|
const statePath = resolveStatePath(ws);
|
||||||
if (!statePath) return;
|
if (!statePath) return;
|
||||||
|
|
||||||
@@ -205,7 +211,7 @@ const plugin = {
|
|||||||
// HOOK 3: before_reset (/new) — archive current state
|
// HOOK 3: before_reset (/new) — archive current state
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
api.on("before_reset", async (_event, _ctx) => {
|
api.on("before_reset", async (_event, _ctx) => {
|
||||||
const ws = getWorkspace();
|
const ws = _ctx?.workspaceDir;
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
if (!ws || config.archiveOnNew === false) return;
|
if (!ws || config.archiveOnNew === false) return;
|
||||||
|
|
||||||
@@ -225,7 +231,7 @@ const plugin = {
|
|||||||
// HOOK 4: agent_end — extract and save working state
|
// HOOK 4: agent_end — extract and save working state
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
api.on("agent_end", async (event, _ctx) => {
|
api.on("agent_end", async (event, _ctx) => {
|
||||||
const ws = getWorkspace();
|
const ws = _ctx?.workspaceDir;
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
if (!ws || config.autoExtract === false) return;
|
if (!ws || config.autoExtract === false) return;
|
||||||
|
|
||||||
@@ -252,7 +258,7 @@ const plugin = {
|
|||||||
// HOOK 5: session_end — ensure state file exists
|
// HOOK 5: session_end — ensure state file exists
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
api.on("session_end", async (_event, _ctx) => {
|
api.on("session_end", async (_event, _ctx) => {
|
||||||
const ws = getWorkspace();
|
const ws = _ctx?.workspaceDir;
|
||||||
const statePath = resolveStatePath(ws);
|
const statePath = resolveStatePath(ws);
|
||||||
if (!statePath) return;
|
if (!statePath) return;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user