LMC Messages in Open Interpreter: Format Specification and Parsing Guide

LMC (Language Model Computer) messages are Python dictionaries with role, type, content, and optional format keys that standardize communication between users, AI assistants, and computer subsystems in Open Interpreter.

Open Interpreter utilizes a custom LMC message format to maintain structured conversations across its execution pipeline. Unlike standard chat APIs, this protocol explicitly distinguishes between conversational content and executable code while preserving execution context. The schema is formally defined in docs/protocols/lmc-messages.mdx and implemented throughout the core interpreter logic.

LMC Message Format Specification

An LMC message is a plain Python dict containing four standardized fields that define the message's origin, payload type, and content structure.

Key Description Required
role Message sender: user, assistant, or computer Yes
type Payload category: message, code, console, image, or audio Yes
content Actual payload data (string for text, list for image URLs) Yes
format Subtype qualifier: python, output, base64, etc. No

The role field determines which subsystem processes the message, while type and format control rendering and execution behavior. For example, a computer role with type: console indicates system output rather than user-facing text.

Example LMC Message Structures


# User query

{"role": "user", "type": "message", "content": "What is 2 + 2?"}

# Assistant generating Python code

{
    "role": "assistant",
    "type": "code",
    "format": "python",
    "content": "print(2+2)"
}

# Computer returning execution results

{
    "role": "computer",
    "type": "console",
    "format": "output",
    "content": "4"
}

# Final assistant response

{"role": "assistant", "type": "message", "content": "The answer is 4."}

How LMC Messages Are Parsed

The parsing pipeline in [interpreter/core/core.py](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/core/core.py) transforms raw execution chunks into structured LMC messages through a multi-stage process.

Receiving Raw Chunks

Computer subsystems stream discrete chunks during code execution, with each chunk representing a partial LMC message. These chunks arrive as dictionaries containing preliminary role, type, and content fields before final assembly.

Start and End Flag Handling

The _respond_and_store method in core.py monitors chunk boundaries using start and end flags. When consecutive chunks share identical role, type, and format values, the interpreter appends their content to a single accumulating message. When these attributes differ, the system emits an end flag for the previous message and a start flag for the new one.


# Logic pattern from _respond_and_store in core.py

if last_flag_base and (same_role_type_format):
    # Append content to existing message

    current_message["content"] += new_chunk["content"]
else:
    # Emit end flag for previous, start flag for new

    finalize_previous_message()
    initialize_new_message()

The helper function is_ephemeral filters transient chunks such as active_line or review markers that should not persist in the final message history.

Merging Chunks into Messages

Successive chunks with matching metadata are concatenated into unified LMC messages stored in interpreter.messages. This merging preserves execution continuity while eliminating fragmentation from streaming output.

Conversion for LLM APIs

Before transmission to providers like OpenAI or Groq, [interpreter/core/llm/utils/convert_to_openai_messages.py](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/core/llm/utils/convert_to_openai_messages.py) transforms the LMC format into provider-native schemas:

  • type: code becomes OpenAI function_call payloads
  • type: image converts to base64-encoded image URLs
  • type: console with format: output renders as function results or standard messages depending on function_calling mode

Conversation Storage

Fully formed LMC messages append to interpreter.messages, which serializes to JSON conversation files when history persistence is enabled. This storage maintains the complete execution context including code inputs and console outputs.

Practical Implementation Examples

Building Custom Language Emitters

Language implementations yield LMC-formatted chunks to integrate with the interpreter's streaming architecture. The E2B profile in [interpreter/terminal_interface/profiles/defaults/e2b.py](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/terminal_interface/profiles/defaults/e2b.py) demonstrates this pattern:

class MyLang:
    """A language that yields LMC-format chunks."""
    name = "mylang"

    def run(self, code):
        result = my_executor.run(code)
        yield {
            "type": "console",
            "format": "output",
            "content": result,
        }

Programmatic Message Injection

Send structured messages directly into the conversation stack:

interpreter = OpenInterpreter()
interpreter.chat(
    {"role": "user", "type": "message", "content": "List files in the current folder."},
    display=False,
)

The chat method validates and appends the dictionary to interpreter.messages without displaying intermediate output.

Converting LMC to OpenAI Format

Transform existing message histories for external API calls:

from interpreter.core.llm.utils import convert_to_openai_messages

openai_payload = convert_to_openai_messages(
    interpreter.messages, 
    function_calling=True, 
    vision=False, 
    interpreter=interpreter
)

This produces a list compatible with openai.ChatCompletion.create or equivalent endpoints.

Key Source Files for LMC Handling

Understanding these files provides complete visibility into the LMC lifecycle:

File Purpose
docs/protocols/lmc-messages.mdx Formal schema documentation and protocol specification
[interpreter/core/core.py](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/core/core.py) Core message loop, chunk merging, and flag management via _respond_and_store
[interpreter/core/llm/utils/convert_to_openai_messages.py](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/core/llm/utils/convert_to_openai_messages.py) Provider-specific format translation logic
[interpreter/terminal_interface/profiles/defaults/e2b.py](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/terminal_interface/profiles/defaults/e2b.py) Reference implementation for custom language LMC emission
[interpreter/core/llm/llm.py](https://github.com/openinterpreter/open-interpreter/blob/main/interpreter/core/llm/llm.py) LLM provider wrapper expecting converted LMC messages

Summary

  • LMC messages standardize Open Interpreter's internal communication using Python dictionaries with role, type, content, and optional format keys.
  • The parsing pipeline in core.py handles chunk streaming, flag management, and message merging to assemble complete conversation history.
  • Format conversion in convert_to_openai_messages.py translates LMC structures to OpenAI-compatible function calls and image payloads.
  • Custom languages integrate by yielding LMC-formatted dictionaries during code execution, as demonstrated in the E2B profile implementation.
  • Complete protocol specifications reside in docs/protocols/lmc-messages.mdx within the openinterpreter/open-interpreter repository.

Frequently Asked Questions

What fields are required in an LMC message?

Every LMC message requires three fields: role (specifying the sender as user, assistant, or computer), type (defining the payload category such as message, code, or console), and content (containing the actual data payload). The format field is optional and provides additional context like python or output to sub-categorize the content.

How does Open Interpreter handle streaming console output?

The interpreter receives console output as discrete chunks through the computer subsystem, then merges consecutive chunks sharing identical role, type, and format values into single LMC messages. The _respond_and_store method in interpreter/core/core.py manages this merging while filtering ephemeral chunks like active_line markers through the is_ephemeral helper function.

Can LMC messages be converted to standard OpenAI format?

Yes, the convert_to_openai_messages function in interpreter/core/llm/utils/convert_to_openai_messages.py transforms LMC dictionaries into OpenAI-compatible structures. Code blocks become function_call objects, images convert to base64-encoded URLs, and console output renders as function results or standard messages depending on the function_calling parameter.

Where is the LMC protocol formally documented?

The complete schema specification resides in docs/protocols/lmc-messages.mdx within the openinterpreter/open-interpreter repository. This file defines valid values for all fields, provides examples, and documents the protocol's design rationale for maintaining structured communication between the user, language model, and execution environment.

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 →