How context-compat.ts Ensures Cross-Runtime Compatibility in the i-have-adhd Extension
The context-compat.ts module acts as an adapter layer that normalizes session-manager APIs between OMP and Pi runtimes, providing runtime-agnostic utilities to query context state without crashing on API differences.
The ayghri/i-have-adhd repository contains a TypeScript extension that must operate consistently across different AI runtime environments. Because the OpenAI-compatible (OMP) and Pi runtimes expose session context through incompatible method signatures, the extension relies on context-compat.ts to abstract these differences and ensure reliable cross-runtime compatibility.
The Runtime Compatibility Challenge
Different runtimes expose session history through distinct APIs. The OMP runtime provides session context via buildSessionContext(), which returns an object containing a messages array. In contrast, the Pi runtime uses buildContextEntries(), which returns the message array directly.
| Runtime | Method | Return Shape |
|---|---|---|
| OMP | buildSessionContext() |
{ messages: readonly ContextMessageMarker[] } |
| Pi | buildContextEntries() |
readonly ContextMessageMarker[] |
Without normalization, extension code would need runtime-specific branches, increasing complexity and fragility.
The Adapter Implementation in context-compat.ts
The module exports two primary utilities that shield consuming code from runtime-specific implementations.
Normalizing Session Manager APIs with contextMessages()
The contextMessages() function detects which API the supplied sessionManager implements. It checks for the existence of buildSessionContext() or buildContextEntries() and calls the appropriate method. The function always returns a plain array of ContextMessageMarker objects, or an empty array if the manager is missing, the call throws, or the result is not an array.
This defensive approach guarantees that calling code never crashes due to unexpected runtime API changes. If the session manager is null, not an object, or lacks expected methods, contextMessages() returns [], allowing the caller to proceed with default behavior.
Evaluating Context State with latestMarkerIsActive()
The latestMarkerIsActive() function walks the normalized messages array looking for custom markers (where role === "custom" and type === "custom_message"). It maintains a Boolean flag that updates when an activeType marker appears and clears when a disabledType marker appears, thus computing whether the most recent marker indicates the rule is active.
Practical Usage in the Extension
Inside extensions/i-have-adhd.ts, the extension consumes these utilities to determine whether ADHD-specific rules should activate:
import { contextMessages, latestMarkerIsActive } from "./context-compat";
export function applyRule(env: RuntimeEnv) {
// Normalise the context irrespective of OMP or Pi runtime
const ctx = contextMessages(env.sessionManager);
// Determine if the ADHD-friendly rule should be active
const adhdActive = latestMarkerIsActive(ctx, "adhd_enabled", "adhd_disabled");
if (adhdActive) {
// …perform rule-specific logic
}
}
Validation Through Testing
The scripts/check_context_compat.ts test script validates this behavior by supplying mock managers implementing each API variant and asserting identical returned message arrays. This ensures that future changes to a runtime's session-manager contract are caught before breaking the extension.
const ompMock = {
buildSessionContext: () => ({ messages: [{ role: "custom", customType: "adhd_enabled" }] })
};
const piMock = {
buildContextEntries: () => [{ role: "custom", customType: "adhd_enabled" }]
};
assert.deepStrictEqual(contextMessages(ompMock), contextMessages(piMock));
assert.strictEqual(
latestMarkerIsActive(contextMessages(ompMock), "adhd_enabled", "adhd_disabled"),
true
);
Summary
- The
context-compat.tsmodule provides an adapter pattern that normalizes incompatible session-manager APIs between OMP and Pi runtimes. - The
contextMessages()function returns a unified array format regardless of whether the runtime usesbuildSessionContext()orbuildContextEntries(). - Defensive programming ensures the extension returns empty arrays rather than crashing when session managers are missing or malformed.
latestMarkerIsActive()interprets custom message markers to determine rule activation state across all supported runtimes.- Comprehensive testing in
scripts/check_context_compat.tsprevents regression when runtime APIs evolve.
Frequently Asked Questions
What runtimes does context-compat.ts support?
The module supports the OMP (OpenAI-compatible) runtime and the Pi runtime. It detects which API is available by checking for the presence of buildSessionContext() for OMP or buildContextEntries() for Pi, allowing seamless operation across both environments.
How does context-compat.ts handle missing or malformed session managers?
The contextMessages() function implements defensive checks: if the session manager is null, not an object, or lacks the expected methods, it returns an empty array []. Similarly, if the method call throws or returns a non-array result, it returns [] rather than propagating the error.
What is the difference between buildSessionContext and buildContextEntries?
buildSessionContext() is the OMP runtime method that returns an object with a messages property containing the context array. buildContextEntries() is the Pi runtime method that returns the context array directly without wrapping it in an object. The contextMessages() function normalizes both to return the unwrapped array.
How does the extension determine if ADHD rules are active?
The extension uses latestMarkerIsActive() to scan the normalized message history for custom markers. It tracks the most recent occurrence of activation and deactivation markers (e.g., "adhd_enabled" vs "adhd_disabled"), returning true only if the latest relevant marker indicates the rule should be active.
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 →