Custom Message Markers for Pi/OMP in i-have-adhd: Complete Technical Guide

i-have-adhd uses two custom message markers—i-have-adhd-rules and i-have-adhd-disabled—to signal ADHD-friendly ruleset activation and deactivation across Pi and OMP runtimes.

The ayghri/i-have-adhd extension implements a marker-based communication protocol that works identically across both the native Pi runtime and the OpenAI-compatible OMP (OpenAI Model Platform) runtime. These markers ensure that ADHD-friendly formatting rules are injected into or removed from the model's context predictably, regardless of which runtime executes the conversation.

The Two Custom Message Markers

The extension defines its markers as string constants in extensions/i-have-adhd.ts:

Marker Constant Value Purpose
RULES_MESSAGE_TYPE "i-have-adhd-rules" Activates the ADHD ruleset—signals Pi/OMP to inject formatting guidelines into context
DISABLED_MESSAGE_TYPE "i-have-adhd-disabled" Deactivates the ruleset—cancels any previous active marker

These declarations appear at lines 23–25 of extensions/i-have-adhd.ts:

const RULES_MESSAGE_TYPE = "i-have-adhd-rules";
const DISABLED_MESSAGE_TYPE = "i-have-adhd-disabled";

The markers function as stateful signals rather than persistent configuration. Each marker supersedes previous ones, with the most recent marker determining whether ADHD mode is active.

How Pi and OMP Handle These Markers

Both runtimes recognize the custom message markers through slightly different internal representations. The compatibility validation in scripts/check_context_compat.ts confirms identical behavior:

OMP Runtime Handling

OMP (OpenAI-compatible) uses a custom-role message structure:

// OMP: custom-role message with customType field
{
  role: "custom",
  customType: "i-have-adhd-rules",  // or "i-have-adhd-disabled"
  content: string,
}

This appears in scripts/check_context_compat.ts lines 6–8.

Pi Runtime Handling

Pi uses a custom_message entry in the context array:

// Pi: custom_message entry with customType field
{
  customType: "i-have-adhd-rules",  // or "i-have-adhd-disabled"
  content: string,
  display: false,
}

This mapping is defined in scripts/check_context_compat.ts lines 27–30.

Despite the structural differences, both runtimes extract the same customType value and apply identical logic to determine ruleset state.

Determining Active Marker State: The latestMarkerIsActive Function

The extensions/context-compat.ts file implements the authoritative logic for interpreting marker sequences. The latestMarkerIsActive function (lines 41–60) walks the context message list and applies last-write-wins semantics:

// From extensions/context-compat.ts, lines 41-60
function latestMarkerIsActive(messages: ContextMessage[]): boolean {
  // Scan messages in reverse (most recent first)
  for (let i = messages.length - 1; i >= 0; i--) {
    const msg = messages[i];
    
    // Skip ordinary user/system messages—they never toggle state
    if (!isCustomMarker(msg)) continue;
    
    if (msg.customType === RULES_MESSAGE_TYPE) {
      return true;   // Most recent marker is ACTIVE
    }
    if (msg.customType === DISABLED_MESSAGE_TYPE) {
      return false;  // Most recent marker is DISABLED
    }
  }
  return false; // Default: no marker found, rules inactive
}

Key implementation details from lines 48–55:

  • Ordinary messages are ignored—user queries and system prompts never accidentally toggle ADHD mode
  • Reverse iteration ensures the newest marker takes precedence
  • Explicit disabled marker allows explicit cancellation without relying on message absence

Practical Implementation: Sending Markers in Code

The extension injects markers through pi.sendMessage() calls in extensions/i-have-adhd.ts (lines 139–158). Both calls use display: false to keep markers invisible to users and triggerTurn: false to prevent unwanted model responses.

Activating ADHD Rules

// extensions/i-have-adhd.ts - activation path
pi.sendMessage(
  {
    customType: RULES_MESSAGE_TYPE,        // "i-have-adhd-rules"
    content: `${RULES_HEADER}\n\n${rules}`,
    display: false,                        // Hidden from user UI
  },
  { triggerTurn: false },                  // Don't trigger model response
);

Deactivating ADHD Rules

// extensions/i-have-adhd.ts - deactivation path
pi.sendMessage(
  {
    customType: DISABLED_MESSAGE_TYPE,     // "i-have-adhd-disabled"
    content: DISABLED_NOTICE,
    display: false,
  },
  { triggerTurn: false },
);

The content field carries human-readable rule text when activating, or a brief notice when disabling. Pi/OMP runtimes primarily examine customType to determine state.

Marker Consistency Validation

The scripts/check_context_compat.ts test suite (referenced throughout the source analysis) verifies that both runtimes:

  1. Preserve marker order in context windows
  2. Respect latestMarkerIsActive logic for state determination
  3. Handle edge cases: empty contexts, duplicate markers, interleaved user messages

This validation ensures that Pi/OMP custom message markers behave identically regardless of which runtime executes the extension.

Summary

  • Two markers control ADHD mode: i-have-adhd-rules (activate) and i-have-adhd-disabled (deactivate), defined in extensions/i-have-adhd.ts
  • Runtime-agnostic protocol: Both Pi and OMP recognize the same customType values through different internal message structures
  • Last-write-wins semantics: latestMarkerIsActive in extensions/context-compat.ts guarantees the newest marker determines state
  • Invisible implementation: All marker messages use display: false and triggerTurn: false to avoid user-visible side effects
  • Validated compatibility: scripts/check_context_compat.ts ensures consistent Pi/OMP behavior

Frequently Asked Questions

What happens if both markers appear in the same context?

The most recent marker wins. The latestMarkerIsActive function scans messages in reverse chronological order, returning true only if i-have-adhd-rules appears after any i-have-adhd-disabled marker. This design allows intentional toggling without requiring marker deletion.

Why use explicit disabled markers instead of just omitting the rules?

Explicit i-have-adhd-disabled markers provide deterministic state cancellation. Without them, long contexts might retain old i-have-adhd-rules markers that accidentally reactivate ADHD mode when the user intended to disable it. The disabled marker creates a clear audit trail of user intent.

Do these markers work with third-party OMP-compatible runtimes?

Any OMP-compatible runtime that properly implements the custom-role message specification will recognize these markers. However, behavior depends on the runtime's handling of unknown customType values—the ayghri/i-have-adhd extension assumes runtimes preserve and expose these fields for context inspection.

Where can I modify the marker constant values?

The RULES_MESSAGE_TYPE and DISABLED_MESSAGE_TYPE constants are defined at lines 23–25 of extensions/i-have-adhd.ts. Changing them requires corresponding updates to extensions/context-compat.ts and scripts/check_context_compat.ts to maintain internal consistency. The values are designed to be unique and collision-resistant with standard message types.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →