Skip to content

Conversation

@anabelle
Copy link
Owner

@anabelle anabelle commented Oct 18, 2025

This PR implements the feature requested in issue #70.

Changes

  • Enhanced Signal Collection: Modified to fetch target post content for zap_thanks memories and include a snippet in the signal format: 'zap_thanks to "[post snippet]": [thanks text]'

  • Updated Prompt Building: Added analysis instructions in to evaluate zaps received on specific posts and identify content patterns that drive engagement

  • Configuration Option: Added setting (default: true) to control the enhanced correlation feature

  • Comprehensive Testing: Added with 11 test cases covering:

    • Successful target post fetching and correlation
    • Truncation of long post content
    • Fallback behavior when targetEventId is missing or fetch fails
    • Configuration-based enabling/disabling
    • Edge cases like missing data properties

Benefits

  • Self-reflection can now learn from specific content that drives zaps, improving future post strategies
  • More precise engagement analysis beyond just zap presence
  • Maintains backward compatibility with graceful fallbacks

Testing

All existing self-reflection tests pass, and the new functionality is thoroughly tested with TDD approach.

Closes #70

Summary by CodeRabbit

  • New Features

    • Added zap correlation capability with new configuration option to enhance signal linking.
    • Zap signals now include truncated target post references when correlation is enabled.
    • Implemented automatic fallback mechanism when correlation data is unavailable.
  • Tests

    • Added comprehensive test suite for zap correlation feature, including configuration handling and various signal scenarios.

…ic post content

- Add zap correlation feature to self-reflection engine
- Fetch target post content for zap_thanks memories and include in signals
- Update prompt to analyze zap signals in context of target posts
- Add NOSTR_SELF_REFLECTION_ZAP_CORRELATION_ENABLE config option (default: true)
- Comprehensive test coverage for zap correlation functionality
- Maintain backward compatibility with fallback to original behavior

Closes #70
Copilot AI review requested due to automatic review settings October 18, 2025 15:07
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR enhances the self-reflection system to correlate zap receipts with the specific post content that generated them, enabling the AI to learn which content patterns drive engagement.

Key Changes:

  • Modified signal collection to fetch and include target post snippets in zap_thanks memories
  • Updated analysis prompts to evaluate content patterns that attract zaps
  • Added configuration toggle (NOSTR_SELF_REFLECTION_ZAP_CORRELATION_ENABLE) with backward-compatible fallbacks

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
plugin-nostr/lib/selfReflection.js Implements async target post fetching in _collectSignalsForInteraction, adds correlation logic with truncation/fallback, and updates analysis prompt with zap pattern evaluation
plugin-nostr/test/selfReflection.zap-correlation.test.js Comprehensive test suite covering successful correlation, truncation, missing data fallbacks, configuration toggling, and edge cases

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 18, 2025

Walkthrough

Implement zap correlation enhancement in self-reflection engine by introducing an async _collectSignalsForInteraction method that fetches original post content for zap_thanks signals when enabled via configuration, enabling deeper LLM analysis of successful engagement patterns.

Changes

Cohort / File(s) Change Summary
Core Zap Correlation Implementation
plugin-nostr/lib/selfReflection.js
Introduced zapCorrelationEnabled config flag from NOSTR_SELF_REFLECTION_ZAP_CORRELATION_ENABLE. Made _collectSignalsForInteraction async. Added logic to fetch target post content for zap_thanks signals when enabled, constructing correlated signals with truncated post snippets. Implemented fallback to original format on fetch failure. Updated all two call sites to await results.
Zap Correlation Test Suite
plugin-nostr/test/selfReflection.zap-correlation.test.js
Added comprehensive test suite covering async signal collection, target post truncation, missing targetEventId fallback, fetch failures, disabled correlation, edge cases (missing/empty data fields), prompt building with correlation analysis instructions, and configuration state handling.

Sequence Diagram

sequenceDiagram
    participant analyze as Analyzer
    participant engine as SelfReflectionEngine
    participant memory as Memory Store
    participant nostr as Nostr Runtime
    
    analyze->>engine: analyze(allMemories, replyMemory)
    engine->>engine: _collectSignalsForInteraction(async)
    
    alt zapCorrelationEnabled && signal.type === 'zap_thanks'
        engine->>memory: getMemoryById(targetEventId)
        memory-->>engine: targetPost (or null)
        
        alt targetPost found
            engine->>nostr: fetch target post content
            nostr-->>engine: post content
            engine->>engine: truncate content (if long)
            engine-->>engine: return correlated signal<br/>with post snippet
        else targetPost missing or fetch fails
            engine-->>engine: return original signal format<br/>(graceful fallback)
        end
    else correlation disabled
        engine-->>engine: return original signal format
    end
    
    engine-->>analyze: signals (correlated or fallback)
    analyze->>engine: _buildPrompt(signals, ...)
    engine->>engine: include zap correlation<br/>analysis instructions
    engine-->>analyze: prompt with context
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Rationale: Logic density is moderate with conditional async operations, configuration reading, and error handling paths. Changes are distributed across signal collection and prompt building logic plus call sites. Test coverage is substantial but follows clear, repetitive patterns. No complex algorithmic changes but requires careful review of async/await correctness and fallback behavior.

Possibly related issues

Poem

🐰 Hops with joy through async ponds,
Zaps now whisper post details beyond,
Correlation blooms where snippets grow,
Self-reflection learns what makes engagement flow! ✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The PR title "Improve Zap Correlation in Self-Reflection to Learn from Specific Post Content" directly and accurately describes the primary change in the changeset. The implementation modifies signal collection to fetch target post content for zap_thanks memories, includes a snippet in the signal format, adds a configuration option for the feature, and provides comprehensive test coverage—all exactly as conveyed by the title. The title is concise, clear, and specific enough for a developer to understand the main purpose when scanning history.
Linked Issues Check ✅ Passed All primary objectives from issue #70 are met in the implementation. The changes enhance signal collection in _collectSignalsForInteraction to fetch target post content for zap_thanks memories and include post snippets in signals [#70]; update prompt building with zap correlation analysis instructions [#70]; introduce the NOSTR_SELF_REFLECTION_ZAP_CORRELATION_ENABLE configuration flag with default true [#70]; and provide comprehensive unit tests covering successful correlation, truncation, missing targetEventId fallback, fetch failures, configuration-based enabling/disabling, and edge cases [#70]. The implementation also includes error handling for fetch failures without aborting, ensuring graceful degradation as specified.
Out of Scope Changes Check ✅ Passed All code changes are directly scoped to the requirements in issue #70. The modifications to plugin-nostr/lib/selfReflection.js implement the specified signal collection enhancements, prompt building updates, and configuration handling. The addition of async/await to _collectSignalsForInteraction and its call sites is a necessary technical change to support the target post fetching functionality. The new test file plugin-nostr/test/selfReflection.zap-correlation.test.js explicitly tests the zap correlation feature as required. No changes appear to address concerns outside the linked issue scope.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/zap-correlation-self-reflection

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@anabelle anabelle merged commit c09539d into master Oct 18, 2025
1 of 2 checks passed
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
plugin-nostr/test/selfReflection.zap-correlation.test.js (2)

120-126: Make truncation assertion more robust.

Length < 250 can fail if zap text is near its 100-char clamp. Prefer asserting the target snippet is truncated and bounded:

  • Extract the quoted snippet via regex and assert it ends with … and length <= 150
  • Keep the existing contains() checks
-      expect(signals[0].length).toBeLessThan(250); // Should be truncated
+      const m = signals[0].match(/zap_thanks to "([^"]+)":/);
+      expect(m).toBeTruthy();
+      const quoted = m[1];
+      expect(quoted.endsWith('…')).toBe(true);
+      expect(quoted.length).toBeLessThanOrEqual(150);

310-318: Strengthen “defaults to enabled” test.

This test only constructs the engine. Also assert that correlation behavior occurs when config is unset.

-      const engine = new SelfReflectionEngine(mockRuntime, console, {});
-
-      // Test that correlation is enabled by default
-      // This is tested implicitly through the other tests
-      expect(engine).toBeDefined();
+      const engine = new SelfReflectionEngine(mockRuntime, console, {});
+      const replyMemory = { id: 'r1', createdAt: Date.now(), content: { text: 'Thanks!' } };
+      const zapMem = {
+        id: 'z1',
+        createdAt: Date.now() - 1000,
+        content: { type: 'zap_thanks', text: '⚡ 42', data: { targetEventId: 't1' } }
+      };
+      mockRuntime.getMemoryById = async () => ({ id: 't1', content: { text: 'Post content' } });
+      const signals = await engine._collectSignalsForInteraction([zapMem], replyMemory, {
+        start: Date.now() - 60000, end: Date.now() + 60000
+      });
+      expect(signals[0]).toContain('zap_thanks to "Post content": ⚡ 42');
plugin-nostr/lib/selfReflection.js (2)

1024-1051: Unify zap text extraction with fallback chain and trim.

Correlated path uses only content.text, while fallback path uses text || data.summary || data.text. This can emit zap_thanks to "…": with a trailing space when text is absent. Align with the fallback chain and trim.

-              if (targetText) {
-                const truncatedTarget = this._truncate(targetText, 150);
-                const zapText = this._truncate(
-                  String(memory.content?.text || ''),
-                  100
-                );
-                signalText = `zap_thanks to "${truncatedTarget}": ${zapText}`;
-              }
+              if (targetText) {
+                const truncatedTarget = this._truncate(targetText, 150);
+                const zapTextRaw = String(
+                  memory.content?.text ||
+                  memory.content?.data?.summary ||
+                  memory.content?.data?.text ||
+                  ''
+                );
+                const zapText = this._truncate(zapTextRaw, 100);
+                signalText = `zap_thanks to "${truncatedTarget}": ${zapText}`.trim();
+              }

1053-1068: Optional: clamp final signal length and guard formatting.

For prompt hygiene and token control, clamp the final signalText length consistently and avoid pushing empty strings.

-      // Fallback to original format if correlation didn't work
+      // Fallback to original format if correlation didn't work
       if (!signalText) {
         const text = this._truncate(
           String(
             memory.content?.text ||
             memory.content?.data?.summary ||
             memory.content?.data?.text ||
             ''
           ),
           200
         );
-        signalText = `${typeLabel}: ${text}`.trim();
+        signalText = `${typeLabel}: ${text}`.trim();
       }
-
-      signals.push(signalText);
+      if (signalText) {
+        signals.push(this._truncate(signalText, 220));
+      }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 648661e and e26cc8b.

📒 Files selected for processing (2)
  • plugin-nostr/lib/selfReflection.js (5 hunks)
  • plugin-nostr/test/selfReflection.zap-correlation.test.js (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
plugin-nostr/test/selfReflection.zap-correlation.test.js (1)
plugin-nostr/lib/selfReflection.js (3)
  • require (1-1)
  • require (2-2)
  • require (3-3)
plugin-nostr/lib/selfReflection.js (4)
plugin-nostr/demo-longitudinal-analysis.js (1)
  • runtime (119-119)
plugin-nostr/show-prompt-example.js (1)
  • runtime (8-11)
plugin-nostr/test-integration-longitudinal.js (1)
  • runtime (106-106)
plugin-nostr/test/selfReflection.prompt.test.js (1)
  • runtime (4-6)
🔇 Additional comments (5)
plugin-nostr/test/selfReflection.zap-correlation.test.js (2)

34-79: Good coverage of enabled correlation path.

Validates target snippet inclusion and basic formatting. LGTM.


239-267: Fallback path coverage looks good.

Covers missing data and no targetEventId. LGTM.

plugin-nostr/lib/selfReflection.js (3)

47-49: Config gate LGTM.

Boolean parsing with sane default true; straightforward and consistent with other flags.


1284-1287: Prompt additions LGTM.

Clear instructions to evaluate zap patterns and tie them to content.


246-251: All call sites properly await _collectSignalsForInteraction; verification complete.

All seven usages across the codebase are correctly awaited:

  • 6 test call sites in plugin-nostr/test/selfReflection.zap-correlation.test.js (lines 74, 120, 152, 189, 233, 263)
  • 1 production call site in plugin-nostr/lib/selfReflection.js (line 250)

No non-awaited calls detected.

anabelle added a commit that referenced this pull request Dec 10, 2025
…ic post content (#73)

- Add zap correlation feature to self-reflection engine
- Fetch target post content for zap_thanks memories and include in signals
- Update prompt to analyze zap signals in context of target posts
- Add NOSTR_SELF_REFLECTION_ZAP_CORRELATION_ENABLE config option (default: true)
- Comprehensive test coverage for zap correlation functionality
- Maintain backward compatibility with fallback to original behavior

Closes #70
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.

Improve Zap Correlation in Self-Reflection to Learn from Specific Post Content

1 participant