What Is `context-compat.ts` in i-have-adhd? Compatibility Layer Explained
The context-compat.ts module normalizes session-manager APIs across Pi and OMP runtimes, allowing the i-have-adhd extension to safely inspect conversation context and determine whether ADHD rules are active.
The i-have-adhd extension, hosted in ayghri/i-have-adhd, must run on two distinct runtime environments—Pi and OMP—that expose different session-manager methods. Located at extensions/context-compat.ts, this compatibility module abstracts away platform differences so the extension can reliably check if its ADHD ruleset is already present in the model's context without crashing on API mismatches.
Why the i-have-adhd Extension Needs Context Compatibility
Language model extensions often need to examine the current conversation history before deciding whether to inject system instructions. However, runtime environments evolve at different paces and expose different APIs.
- Pi runtime provides
buildContextEntries(), returning an array of custom message objects directly. - OMP runtime provides
buildSessionContext(), returning an object where themessagesproperty contains the array.
Hardcoding either method would break the extension on the other platform. The context-compat.ts module eliminates this coupling through a unified interface.
Core Functions in context-compat.ts
The module exports two essential functions that power the extension's conditional logic.
contextMessages(sessionManager): Normalizing the API
This function returns a plain array of ContextMessageMarker regardless of which runtime method is available.
import { contextMessages } from "./context-compat";
// Works identically for both Pi and OMP managers
const messages = contextMessages(ctx.sessionManager);
Fail-open handling ensures robustness: if the session manager is null, not an object, or throws during context building, the function returns an empty array. This prevents startup crashes and allows graceful degradation.
latestMarkerIsActive(messages, activeType, disabledType): Evaluating State
This function determines whether ADHD rules are currently "live" by walking through message markers.
import { latestMarkerIsActive } from "./context-compat";
const rulesActive = latestMarkerIsActive(
messages,
"i-have-adhd-rules", // active marker type
"i-have-adhd-disabled", // disabled marker type
);
The logic returns true only if the most recent custom marker of activeType has not been overridden by a later disabledType marker. This supports toggleable behavior where users can disable and re-enable the ruleset mid-conversation.
How i-have-adhd.ts Uses the Compatibility Layer
The main extension logic in extensions/i-have-adhd.ts delegates context inspection to these helpers:
import { contextMessages, latestMarkerIsActive } from "./context-compat";
function rulesAreInContext(ctx: ExtensionContext): boolean {
return latestMarkerIsActive(
contextMessages(ctx.sessionManager),
"i-have-adhd-rules",
"i-have-adhd-disabled",
);
}
This single call works across both runtimes because contextMessages has already normalized the underlying API differences.
Testing the Compatibility Layer
The repository includes standalone verification in scripts/check_context_compat.ts:
import {
contextMessages,
latestMarkerIsActive,
} from "../extensions/context-compat";
const ACTIVE = "i-have-adhd-rules";
const DISABLED = "i-have-adhd-disabled";
// OMP-style manager
const ompMgr = {
buildSessionContext: () => ({ messages: [{ role: "custom", customType: ACTIVE }] })
};
console.assert(contextMessages(ompMgr).length === 1);
// Pi-style manager
const piMgr = {
buildContextEntries: () => [{ type: "custom_message", customType: ACTIVE }]
};
console.assert(contextMessages(piMgr).length === 1);
// Marker evaluation logic
const markers = [
{ role: "custom", customType: ACTIVE },
{ role: "custom", customType: DISABLED },
{ role: "custom", customType: ACTIVE },
];
console.assert(latestMarkerIsActive(markers, ACTIVE, DISABLED));
These assertions verify that the abstraction correctly handles both runtime shapes and properly evaluates activation state.
Summary
context-compat.tsbridges Pi and OMP session-manager APIs through normalized functions.contextMessages()extracts message arrays safely, with defensive fallbacks for missing or broken managers.latestMarkerIsActive()implements toggle-state logic to detect whether ADHD rules are currently active.- The module enables
i-have-adhd.tsto remain runtime-agnostic and resilient to API changes. - Comprehensive checks in
scripts/check_context_compat.tsvalidate cross-platform behavior.
Frequently Asked Questions
What problem does context-compat.ts solve in the i-have-adhd extension?
It eliminates hard dependencies on runtime-specific session-manager APIs. Pi uses buildContextEntries() while OMP uses buildSessionContext(), and this module provides a single interface that works with both, preventing platform-specific crashes.
How does context-compat.ts handle missing or broken session managers?
The contextMessages() function implements fail-open handling: it returns an empty array if the manager is null, not an object, or throws an exception. This ensures the extension starts cleanly even when session management is unavailable.
What determines whether ADHD rules are considered "active" in the context?
The latestMarkerIsActive() function scans for custom message markers. It returns true only if the most recent marker of the active type (e.g., "i-have-adhd-rules") appears after any disabling marker of the disabled type (e.g., "i-have-adhd-disabled"). This supports mid-conversation toggling.
Where can I find the actual ADHD ruleset that gets injected?
The ruleset content lives in skills/i-have-adhd/SKILL.md. The context-compat.ts module only determines whether injection is needed; the skill file contains the actual behavioral instructions provided to the language model.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →