Building with Morpheus
Learn how to create, run, and evolve semantic object-based systems using the Morpheus runtime engine. This guide walks you through designing reactive logic, defining hooks, and triggering behaviors—building intelligent, self-managed software using semantic data.
1. Understanding Execution in Morpheus
Morpheus is designed to execute behavior stored inside data objects. These behaviors are defined as hooks, which are small functions that run in response to events or timers.
Each semantic object may include:
onTick
— executed on a scheduleonEvent
— executed when an event is receivedonCreate
,onDelete
— optionally for lifecycle events
Morpheus processes these hooks in a secure runtime and can trigger other objects by emitting events.
2. Creating a Semantic Object
Here’s an example of a simple counter object that responds to time and events:
{
"@context": "https://schema.sodea.org/core#",
"@id": "urn:demo:counter",
"@type": "CounterObject",
"counter": 0,
"status": "idle",
"_private": {
"hooks": {
"onTick": {
"language": "python",
"code": "def run(obj, params, save, load, delete):\n obj['counter'] += 1\n save(obj)\n return obj"
}
},
"schedule": {
"interval": "5s"
}
}
}
Save this object via the Morpheus API, and it will begin incrementing its counter
every 5 seconds.
3. Writing Hooks
Hooks are stored as executable code inside your object. Morpheus currently supports:
Python
for dynamic backend logicJavaScript
(optional configuration)
A hook must define a run(obj, params, save, load, delete)
function and can:
- Read/modify the object (
obj
) - Save changes
- Trigger events by returning a
trigger_event
Example of triggering an event:
if obj['counter'] > 100:
return { "trigger_event": { "eventType": "threshold", "payload": { "value": obj['counter'] } } }
4. Event-Based Execution
You can subscribe to event types via the _private.subscriptions
field. When an event is published, Morpheus will call your object’s onEvent
hook if the event type matches.
"subscriptions": ["threshold", "reset"]
And the hook:
def run(obj, params, save, load, delete):
if params.get("eventType") == "reset":
obj["counter"] = 0
save(obj)
return obj
5. Monitoring Execution
All hook executions can log output to the console, visible in your admin dashboard or frontend interface (like Fountain).
Use print("something happened")
to trace logic during development.
6. Advanced Patterns
- Graph-based chaining: One object can trigger another by sending events.
- Stateful interactions: Objects can persist state, making them long-lived agents.
- Data-driven control: Behavior adapts based on fields in the object itself.
Example: A counter that slows down over time by adjusting its own interval.
7. Running Morpheus
Morpheus can run in multiple environments:
- As a local dev server (default)
- As a Flask/FastAPI app (custom deployment)
- With different storage layers: flat file, MongoDB, etc.
It is open-source and easily extended.
8. Integrating with Fountain
Fountain is the recommended frontend for viewing, editing, and testing semantic objects.
Use Fountain to:
- Visually browse the semantic object graph
- Inspect logs
- Trigger hooks
- Create new templates
9. What’s Next?
Now that you can build reactive systems with Morpheus:
- Read the API Reference to learn how to submit and retrieve objects
- Try Sample Projects
- Build your own AI-enhanced semantic agents
---