@happycastle/oh-my-openclaw 0.13.2 → 0.13.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,10 @@
1
1
  import { OmocPluginApi } from '../types.js';
2
+ /**
3
+ * Check whether persona content is already present in session history.
4
+ *
5
+ * OpenClaw's `prependContext` is merged into the user prompt and persisted
6
+ * in session history. Without this check the persona text accumulates —
7
+ * appearing once per historical user message sent to the model.
8
+ */
9
+ export declare function isPersonaAlreadyInHistory(messages: unknown[] | undefined, personaContent: string): boolean;
2
10
  export declare function registerPersonaInjector(api: OmocPluginApi): void;
@@ -24,6 +24,33 @@ async function resolveEffectivePersona(ctx) {
24
24
  return null;
25
25
  return { personaId: resolved, source: 'auto' };
26
26
  }
27
+ const FINGERPRINT_LENGTH = 200;
28
+ /**
29
+ * Check whether persona content is already present in session history.
30
+ *
31
+ * OpenClaw's `prependContext` is merged into the user prompt and persisted
32
+ * in session history. Without this check the persona text accumulates —
33
+ * appearing once per historical user message sent to the model.
34
+ */
35
+ export function isPersonaAlreadyInHistory(messages, personaContent) {
36
+ if (!messages || messages.length === 0)
37
+ return false;
38
+ const fingerprint = personaContent.slice(0, FINGERPRINT_LENGTH).trim();
39
+ if (!fingerprint)
40
+ return false;
41
+ for (const msg of messages) {
42
+ if (!msg || typeof msg !== 'object')
43
+ continue;
44
+ const record = msg;
45
+ if (record['role'] !== 'user')
46
+ continue;
47
+ const content = record['content'];
48
+ if (typeof content === 'string' && content.includes(fingerprint)) {
49
+ return true;
50
+ }
51
+ }
52
+ return false;
53
+ }
27
54
  export function registerPersonaInjector(api) {
28
55
  // Use the typed hook system (api.on) for before_prompt_build.
29
56
  // This directly injects into the system prompt via prependContext,
@@ -32,7 +59,7 @@ export function registerPersonaInjector(api) {
32
59
  // api.registerHook('before_prompt_build', ...) registers into the internal
33
60
  // hook system which does NOT trigger before_prompt_build — only hookRunner
34
61
  // (typed hooks via api.on) does.
35
- api.on('before_prompt_build', async (_event, ctx) => {
62
+ api.on('before_prompt_build', async (event, ctx) => {
36
63
  const result = await resolveEffectivePersona(ctx);
37
64
  if (!result) {
38
65
  const manual = await getActivePersona();
@@ -42,6 +69,10 @@ export function registerPersonaInjector(api) {
42
69
  const { personaId, source } = result;
43
70
  try {
44
71
  const content = readPersonaPromptSync(personaId);
72
+ if (isPersonaAlreadyInHistory(event.messages, content)) {
73
+ api.logger.info(`${LOG_PREFIX} Persona already in history, skipping injection: ${personaId} (${source})`);
74
+ return;
75
+ }
45
76
  api.logger.info(`${LOG_PREFIX} Persona injected via before_prompt_build: ${personaId} (${source}, agentId=${ctx.agentId ?? 'none'})`);
46
77
  return {
47
78
  prependContext: content,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happycastle/oh-my-openclaw",
3
- "version": "0.13.2",
3
+ "version": "0.13.4",
4
4
  "description": "Oh-My-OpenClaw plugin — multi-agent orchestration, todo enforcer, ralph loop, and custom tools for OpenClaw",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",