Formatting and History Serialization
Relevant source files
The following files were used as context for generating this wiki page:
The formatting and history serialization system in the oh-my-pi-plugin-morph repository provides the critical infrastructure for bridging local agent activity with Morph LLM remote services. Its primary purpose is to transform complex, multi-modal session data (text, tool calls, and results) into a structured, condensed format suitable for the Morph Compact API while enforcing safety constraints like symlink containment and truncation detection.
This system ensures that conversation history is properly serialized for compaction, code edits are validated for safety, and search results are formatted into a structured XML-like schema for the agent to consume. By managing data egress and ingress, it maintains the integrity of the workspace while leveraging remote LLM capabilities for long-term context management.
Message Serialization Architecture
The serialization logic converts internal oh-my-pi message shapes into a simplified MorphCompactMessage format (role and content). This process includes stripping multi-modal content like images and thinking blocks that are not relevant for text-based history compaction.
Serialization Flow
The following diagram illustrates how different message types are processed into a unified format for Morph.
The system uses a bounded buffer strategy to prevent memory exhaustion when materializing large tool results or arguments. Tool results are capped at 2,000 characters, while tool call arguments are capped at 500 characters.
Sources: src/compaction.ts:86-126, src/compaction.ts:139-160
Key Serialization Functions
| Function | Purpose | Constraints |
|---|---|---|
serializeAgentMessagesForMorph | Main entry point for converting session history. | Filters out empty messages. |
serializeMessageContent | Orchestrates content extraction based on role. | Enforces 2000-char tool result limit. |
boundedJsonStringify | Safely serializes objects to JSON strings. | Stops execution when limit is reached. |
serializeContentPart | Maps specific part types (text, toolCall) to strings. | Ignores thinking and image types. |
Sources: src/compaction.ts:133-176
Code Edit and Path Validation
When performing code modifications via fast_edit, the system performs rigorous validation to prevent "catastrophic truncation" and "marker leakage." It also ensures that file paths do not escape the workspace root, even through symlinks.
Path Safety and Symlink Containment
The resolveFilepath function validates that requested paths are relative and anchored within the cwd. It implements a recursive symlink check that walks every component of the path to ensure a symlink doesn't point to a target outside the workspace.
Merge Validation
To protect codebase integrity during AI-driven merges, the system checks the output of morph.fastApply.
- Marker Leakage: Detects if the
// ... existing code ...marker (defined byEXISTING_CODE_MARKER) appears in the final output when it wasn't in the original file. This prevents the LLM from treating markers as literal text. - Catastrophic Truncation: Compares line and character counts between original and merged versions. A trigger occurs if character loss exceeds 60% and line loss exceeds 50% while markers were used.
Sources: src/format.ts:101-125, src/config.ts:13
Search Result Formatting
The formatWarpGrepResult utility transforms raw search contexts from codebase_warpsearch and github_warpsearch into a human-readable and agent-parsable string.
Data Model and XML Envelope
Search results are encapsulated in an XML-like structure to preserve path and line metadata. The formatter performs XML entity escaping on both file paths and content to prevent injection attacks or malformed structures.
| Element | Attribute | Content |
|---|---|---|
<file> | path | The escaped relative path of the file. |
<file> | lines | The range of lines (e.g., 10-20,45-50) or *. |
| Content | N/A | The actual source code context, XML-escaped. |
Sources: src/format.ts:135-181
Formatting Logic Sequence
Sources: src/format.ts:149-181
Configuration and Defaults
The serialization behavior is influenced by several environmental constants and configuration flags.
| Variable | Source | Default | Description |
|---|---|---|---|
COMPACT_RATIO | src/config.ts | 0.3 | Target fraction of history to retain during compaction. |
EXISTING_CODE_MARKER | src/config.ts | // ... existing code ... | The string used to identify unchanged blocks in edits. |
FASTCOMPACT_MAX_BYTES | src/config.ts | 1,048,576 | Maximum size for a single file compaction input. |
MORPH_ROUTING_HINT_HEADER | src/config.ts | Morph plugin routing hints: | Header for system-level tool selection guidance. |
Sources: src/config.ts:1-35
Conclusion
The Formatting and History Serialization module serves as the primary data validator and transformer for the Morph plugin. By enforcing strict limits on JSON serialization, validating code merges for data loss, and securing file access through symlink-aware path resolution, it provides a robust foundation for remote LLM operations within a local development environment. These mechanisms collectively ensure that the communication between the local oh-my-pi agent and the Morph API is safe, efficient, and semantically accurate.