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: codebecomes OpenAIfunction_callpayloadstype: imageconverts to base64-encoded image URLstype: consolewithformat: outputrenders as function results or standard messages depending onfunction_callingmode
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 optionalformatkeys. - The parsing pipeline in
core.pyhandles chunk streaming, flag management, and message merging to assemble complete conversation history. - Format conversion in
convert_to_openai_messages.pytranslates 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.mdxwithin 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →