POM technical reference
Introduction
This technical reference provides comprehensive documentation for developers working with the Prompt Object Model (POM) library. To learn more about what the Prompt Object Model is, see the POM overview.
POM format specification
The POM is a JSON array of section objects with specific requirements based on position and nesting:
Field | Required | Description |
---|---|---|
title | No | Heading text |
body | One of body or bullets required | Paragraph or long-form instruction text |
bullets | One of body or bullets required | Non-empty array of short statements/rules |
subsections | No | Nested list of sections |
numbered | No | Boolean indicating if section should be numbered |
numberedBullets | No | Boolean indicating if bullets should be numbered |
JSON schema for POM
Users can refer to the following JSON schema and basic example below for the POM structure:
- JSON Schema
- Basic Example
{
"$schema": "https://json-schema.org/draft-07/schema",
"$id": "https://example.com/pom.schema.json",
"title": "Prompt Object Model",
"type": "array",
"items": { "$ref": "#/$defs/section" },
"$defs": {
"section": {
"type": "object",
"properties": {
"title": { "type": "string" },
"body": { "type": "string" },
"bullets": {
"type": "array",
"items": { "type": "string" }
},
"subsections": {
"type": "array",
"items": { "$ref": "#/$defs/section" }
},
"numbered": { "type": "boolean" },
"numberedBullets": { "type": "boolean" }
},
"anyOf": [
{ "required": ["body"] },
{ "required": ["bullets"] }
],
"additionalProperties": false
}
}
}
[
{
"body": "You are a helpful AI assistant with specific capabilities.",
"bullets": [
"Follow user instructions carefully",
"Maintain professional tone"
],
"numbered": true,
"subsections": [
{
"title": "Communication Style",
"body": "When communicating, follow these guidelines:",
"numberedBullets": true,
"bullets": [
"Be clear and concise",
"Use professional language"
]
}
]
},
{
"title": "Task Execution",
"body": "When executing tasks, follow this process:",
"bullets": [
"Understand the requirements fully",
"Plan the approach",
"Execute carefully"
],
"numbered": true
}
]
Core classes
The library consists of two main classes:
Class | Description |
---|---|
PromptObjectModel | The main container that holds all sections and provides top-level functionality |
Section | Represents a single section in the prompt hierarchy with content and structure |
PromptObjectModel class
The PromptObjectModel
class is the main entry point for creating and managing prompt objects.
Constructing a new POM
from signalwire_pom import PromptObjectModel
# Create a new POM
pom = PromptObjectModel()
Methods
Method | Description |
---|---|
add_section | Adds a top-level section to the prompt POM. |
find_section | Finds a section by its title, searching recursively through all sections and subsections. |
to_json | Converts the entire POM to a JSON string. |
to_yaml | Converts the entire POM to a YAML string. |
to_dict | Converts the entire POM to a list of dictionaries. |
render_markdown | Renders the entire POM as markdown. |
render_xml | Renders the entire POM as XML. |
from_json | Creates a PromptObjectModel instance from JSON data. |
from_yaml | Creates a PromptObjectModel instance from YAML data. |
add_pom_as_subsection | Adds another POM as a subsection to a specified section. |
add_section
Adds a top-level section to the prompt POM.
Parameters:
Parameter | Type | Default Value | Description |
---|---|---|---|
title Optional | Optional[str] | - | The title of the section |
body Optional | str | '' | Body text for the section |
bullets Optional | Union[List[str], str] | - | List of bullet points or a single string (which will be converted to a single-item list) |
numbered Optional | Optional[bool] | None | Whether this section should be numbered |
numberedBullets Optional | bool | False | Whether bullets should be numbered instead of using bullet points |
Returns:
Type | Description |
---|---|
Section | The newly created section object |
Example:
# Create a section with a title and body
rules = pom.add_section(
"Rules",
body="Follow these important guidelines:"
)
# Add bullet points
rules.add_bullets([
"Never send emails on behalf of the user",
"Maintain user privacy and confidentiality"
])
find_section
Finds a section by its title, searching recursively through all sections and subsections.
Parameters:
Parameter | Type | Default Value | Description |
---|---|---|---|
title Required | str | - | The title to search for |
Returns:
Type | Description |
---|---|
Optional[Section] | The found section or None if not found |
Example:
# Find a section by its title
rules_section = pom.find_section("Rules")
if rules_section:
# Modify the found section
rules_section.add_bullets(["Always suggest proofreading before sending"])
to_json
Converts the entire POM to a JSON string.
Parameters: None
Returns:
Type | Description |
---|---|
str | JSON string representation of the POM |
Example:
# Generate JSON representation
json_data = pom.to_json()
print(json_data)
to_yaml
Converts the entire POM to a YAML string.
Parameters: None
Returns:
Type | Description |
---|---|
str | YAML string representation of the POM |
Example:
# Generate YAML representation
yaml_data = pom.to_yaml()
print(yaml_data)
to_dict
Converts the entire POM to a list of dictionaries.
Parameters: None
Returns:
Type | Description |
---|---|
List[dict] | List of dictionaries representing each section in the POM |
Example:
# Convert POM to dictionary representation
dict_data = pom.to_dict()
print(dict_data)
render_markdown
Renders the entire POM as markdown. The method will follow the below logic when rendering the POM as markdown:
Rendering Logic:
- Top-level sections with titles are rendered as
##
(h2 headings) - Each level of nesting increases the heading level (h3, h4, etc.)
- Body text appears after the heading
- Bullet points are rendered as markdown list items with
-
prefix - Proper line spacing is maintained between elements
Parameters: None
Returns:
Type | Description |
---|---|
str | Markdown representation of the POM |
Example:
from signalwire_pom import PromptObjectModel
# Create a new POM
pom = PromptObjectModel()
# Add a section with title and body
section = pom.add_section(
"System instructions",
body="You are a helpful AI assistant."
)
# Add bullet points
section.add_bullets([
"Answer user questions accurately",
"Be concise and clear"
])
sub_section = section.add_subsection(
"Subsection 1",
body="This is the body of the subsection."
)
sub_section.add_bullets([
"Answer user questions accurately",
"Be concise and clear"
])
# Render as markdown
markdown = pom.render_markdown()
print(markdown)
Output:
## System instructions
You are a helpful AI assistant.
- Answer user questions accurately
- Be concise and clear
### Subsection 1
This is the body of the subsection.
- Answer user questions accurately
- Be concise and clear
render_xml
Renders the entire POM as XML. The method will follow the below logic when rendering the POM as XML:
Rendering Logic:
- The POM is wrapped in a root
<prompt>
element - Each section is represented as a
<section>
element - Section properties are rendered as child elements:
<title>
for the section title<body>
for the section body text<bullets>
containing individual<bullet>
elements<subsections>
containing nested<section>
elements
Parameters:
Parameter | Type | Default Value | Description |
---|---|---|---|
indent Optional | int | 0 | The indentation level to start with (default: 0) |
Returns:
Type | Description |
---|---|
str | XML representation of the POM |
Example:
# Using the same POM from the previous example
xml = pom.render_xml()
print(xml)
Output:
<?xml version="1.0" encoding="UTF-8"?>
<prompt>
<section>
<title>System instructions</title>
<body>You are a helpful AI assistant.</body>
<bullets>
<bullet>Answer user questions accurately</bullet>
<bullet>Be concise and clear</bullet>
</bullets>
<subsections>
<section>
<title>Subsection 1</title>
<body>This is the body of the subsection.</body>
<bullets>
<bullet>Answer user questions accurately</bullet>
<bullet>Be concise and clear</bullet>
</bullets>
</section>
</subsections>
</section>
</prompt>
from_json
Creates a PromptObjectModel instance from JSON data.
Parameters:
Parameter | Type | Default Value | Description |
---|---|---|---|
json_data Required | Union[str, dict] | - | Either a JSON string or a parsed dictionary |
Returns:
Type | Description |
---|---|
PromptObjectModel | A new instance populated with data from the JSON |
Example:
# Create a POM from JSON
json_string = '''
[
{
"title": "Knowledge",
"body": "You have the following specific knowledge:",
"bullets": ["Email etiquette", "Business terminology"],
"subsections": []
}
]
'''
knowledge_pom = PromptObjectModel.from_json(json_string)
from_yaml
Creates a PromptObjectModel instance from YAML data.
Parameters:
Parameter | Type | Default Value | Description |
---|---|---|---|
yaml_data Required | Union[str, dict] | - | Either a YAML string or a parsed dictionary |
Returns:
Type | Description |
---|---|
PromptObjectModel | A new instance populated with data from the YAML |
Example:
# Create a POM from YAML
yaml_string = '''
- title: Knowledge
body: You have the following specific knowledge
bullets:
- Email etiquette
- Business terminology
subsections: []
'''
knowledge_pom = PromptObjectModel.from_yaml(yaml_string)
add_pom_as_subsection
Adds another PromptObjectModel as a subsection to a section with the given title or section object.
Parameters:
Parameter | Type | Default Value | Description |
---|---|---|---|
target Required | Union[str, Section] | - | The title of the section or the Section object to add to |
pom_to_add Required | PromptObjectModel | - | The PromptObjectModel to add as a subsection |
Returns:
Type | Description |
---|---|
None | This method doesn't return a value |
Raises:
ValueError
: If no section with the target title is found (when target is a string)TypeError
: If target is neither a string nor a Section object
Example:
# Create two POMs
base_pom = PromptObjectModel()
base_section = base_pom.add_section("Base Section", body="Main content")
additional_pom = PromptObjectModel()
additional_pom.add_section("Additional Content", body="Extra information")
# Add the additional POM as a subsection
base_pom.add_pom_as_subsection("Base Section", additional_pom)
Section class
The Section
class represents a single section in the POM hierarchy and provides methods for managing content and structure.
A section can be accessed through a instance of the PromptObjectModel
class.
Constructing a new Section
from signalwire_pom import PromptObjectModel
# Create a new POM
pom = PromptObjectModel()
# Add a section to the POM
section = pom.add_section("Section title", body="This is the main content of my section.")
Methods
Method | Description |
---|---|
add_body | Adds or replaces the body text for this section. |
add_bullets | Adds bullet points to this section. |
add_subsection | Adds a subsection to this section. |
to_dict | Converts the section to a dictionary representation. |
render_markdown | Renders this section and all its subsections as markdown. |
render_xml | Renders this section and all its subsections as XML. |
add_body
Adds or replaces the body text for this section.
Parameters:
Parameter | Type | Default Value | Description |
---|---|---|---|
body Required | str | - | The text to set as the section body |
Returns:
Type | Description |
---|---|
None | This method doesn't return a value |
Example:
section = pom.add_section("Section title")
section.add_body("This is the main content of my section.")
add_bullets
Adds bullet points to this section.
Parameters:
Parameter | Type | Default Value | Description |
---|---|---|---|
bullets Required | List[str] | - | List of bullet points to add |
Returns:
Type | Description |
---|---|
None | This method doesn't return a value |
Example:
section = pom.add_section("Guidelines")
section.add_bullets([
"First important point",
"Second important point",
"Third important point"
])
add_subsection
Adds a subsection to this section.
Parameters:
Parameter | Type | Default Value | Description |
---|---|---|---|
title Optional | str | - | The title of the subsection |
body Optional | str | - | Optional body text for the subsection |
bullets Optional | Optional[List[str]] | - | Optional list of bullet points |
Returns:
Type | Description |
---|---|
Section | The newly created subsection |
Example:
capabilities = pom.add_section("Capabilities")
drafting = capabilities.add_subsection(
"Email drafting",
body="Create email drafts based on user specifications."
)
drafting.add_bullets([
"Format emails properly with greeting, body, and signature",
"Adjust tone based on recipient and purpose"
])
to_dict
Converts the section to a dictionary representation.
Parameters: None
Returns:
Type | Description |
---|---|
dict | Dictionary representation of the section |
Example:
section = pom.add_section("Test section")
section_dict = section.to_dict()
render_markdown
Renders this section and all its subsections as markdown. The method will follow the below logic when rendering the section as markdown:
Rendering Logic:
- The section title is rendered as a heading, with heading level based on nesting depth
- The heading level starts at the provided
level
parameter (default: 2, which is##
) - Body text appears after the heading with a blank line
- Bullet points are rendered as markdown list items with
-
prefix - Subsections are rendered with incremented heading levels to show hierarchy
- If a section has no title (only valid at root level), its content is rendered directly
Parameters:
Parameter | Type | Default Value | Description |
---|---|---|---|
level Optional | int | 2 | The heading level to start with (default: 2, which corresponds to ##) |
Returns:
Type | Description |
---|---|
str | Markdown representation of the section |
Example:
# Using a section from the previous example
section_markdown = section.render_markdown()
print(section_markdown)
Output:
## System instructions
You are a helpful AI assistant.
- Answer user questions accurately
- Be concise and clear
### Subsection 1
This is the body of the subsection.
- Answer user questions accurately
- Be concise and clear
render_xml
Renders this section and all its subsections as XML. The method will follow the below logic when rendering the section as XML:
Rendering Logic:
- The section is represented as a
<section>
element - Section properties are rendered as child elements:
<title>
for the section title (if present)<body>
for the section body text (if present)<bullets>
containing individual<bullet>
elements (if present)<subsections>
containing nested<section>
elements (if present)
Parameters:
Parameter | Type | Default Value | Description |
---|---|---|---|
indent Optional | int | 0 | The indentation level to start with (default: 0) |
Returns:
Type | Description |
---|---|
str | XML representation of the section |
Example:
# Using a section from the previous example
section_xml = section.render_xml()
print(section_xml)
Output:
<section>
<title>System instructions</title>
<body>You are a helpful AI assistant.</body>
<bullets>
<bullet>Answer user questions accurately</bullet>
<bullet>Be concise and clear</bullet>
</bullets>
<subsections>
<section>
<title>Subsection 1</title>
<body>This is the body of the subsection.</body>
<bullets>
<bullet>Answer user questions accurately</bullet>
<bullet>Be concise and clear</bullet>
</bullets>
</section>
</subsections>
</section>
Command line interface
The POM library includes a command-line interface (CLI) tool for working with POM files. The CLI allows you to convert between different formats and merge POM files.
Usage
pom_tool <input_file> [--output=<format>] [--outfile=<file>] [--merge_pom="<section name>:<filename>"]
Arguments
Argument | Description |
---|---|
input_file Required | Path to the input POM file (JSON or YAML format) |
Options
Option | Default | Description |
---|---|---|
-h, --help Optional | - | Show help message |
--output=<format> Optional | md | Output format: md , xml , json , yaml |
--outfile=<file> Optional | - | Output file path (if not specified, prints to stdout) |
--merge_pom=<arg> Optional | - | Merge another POM file into a section: "<section name>:<filename>" |
Error handling
The tool handles several error conditions:
- Invalid output format: Returns an error if the specified output format is not one of:
md
,xml
,json
,yaml
- File parsing errors: Reports JSON/YAML parsing errors with descriptive messages
- Section not found: When using
--merge_pom
, reports if the target section is not found - Invalid merge syntax: Validates the
section:filename
format for the merge option
Examples
- Convert a JSON POM file to Markdown:
pom_tool input.json --output=md
- Convert a YAML POM file to XML and save to file:
pom_tool input.yaml --output=xml --outfile=output.xml
- Merge two POM files:
pom_tool base.json --merge_pom="System Instructions:additional.json" --output=json
- Show help message:
pom_tool --help