observe operations
The exact fields each observe.* operation takes and returns.
Every op is POST /v1/<op> over HTTP and the MCP tool loom_<op>. The identity fields (org, namespace, agent, user_id, session_id) are filled from the token and the MCP session when a transport can; for an HTTP call with no token on a single-user server, the install's org on every op but code.* and tracker.* (which keep their plane's), and on some ops its namespace and agent; see identities and namespaces. The operations index explains role, kind and the MCP all listing. Unknown input fields are served and named in ignored_args.
observe.crystallize
Mark a session's pending observations ready for extraction into memories (queues only).
POST /v1/observe.crystallize · MCP loom_observe_crystallize · role writer · idempotent
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
agent |
str |
required | The writing or reading agent; '-' or '*' means any agent where the op allows it. |
user_id |
str |
'-' |
The end user the row belongs to; '-' for none. |
session_id |
str |
'-' |
The session or conversation the row belongs to; '-' for none. |
max_observations |
int |
500 |
At most this many pending observations of the session are marked ready, oldest first. |
| Output field | Type | Meaning |
|---|---|---|
enqueued |
int |
How many observations were marked crystallize:ready for the extraction worker; 0 when the session had none pending. |
session_id |
str |
The session or conversation the row belongs to; '-' for none. |
observe.record
Record one tool observation (input, output, files, error) into the episodic plane; no LLM call.
POST /v1/observe.record · MCP loom_observe_record · role writer · idempotent
| Input field | Type | Default | Meaning |
|---|---|---|---|
org |
str |
required | The tenant (first element of the identity tuple). |
namespace |
str |
required | The namespace the op reads or writes. |
agent |
str |
required | The writing or reading agent; '-' or '*' means any agent where the op allows it. |
user_id |
str |
'-' |
The end user the row belongs to; '-' for none. |
session_id |
str |
'-' |
The session or conversation the row belongs to; '-' for none. |
run_id |
str |
'-' |
The agent run (task scope) the call belongs to; '-' for none. |
tool_name |
str |
required | Name of the tool that ran; it picks the observation kind by substring match. |
tool_input |
dict[str, Any] \| list[Any] \| str \| int \| float \| bool \| None |
None |
Arbitrary JSON forwarded by the hook; stringified + truncated, never executed. |
tool_output |
dict[str, Any] \| list[Any] \| str \| int \| float \| bool \| None |
None |
What the tool returned; stringified and cut to 800 characters in the narrative. |
file_paths |
list[str] |
(computed) | Merged with paths sniffed from the input/narrative. |
error |
str \| None |
None |
Present iff the call failed; reclassifies the observation kind to error. |
tags |
list[str] |
(computed) | Extra tags added after the server's own (observation, the kind, file basenames); at most 32 tags are kept in all. |
observation_date |
str |
'' |
ISO YYYY-MM-DD stamped as valid_at; empty = leave NULL. |
action_type |
str |
'' |
The client's own action class (file_read, command_run, …), added as an action:<type> tag. |
metadata |
dict[str, Any] |
(computed) | Client context (project, repo, event); accepted, not stored. |
observed_at |
str |
'' |
The moment the tool ran, so a capture posted later is dated when it happened. |
| Output field | Type | Meaning |
|---|---|---|
memory_key |
str |
Key of the episodic row, obs:<session_id>:<hash prefix>; a re-fired hook for the same call gets the same key. |
memory_id |
str |
Always empty: the row's id is assigned by the table and not read back. |
kind |
str |
file_edit / command_run / error / web_fetch / file_read / tool_use. |
tags |
list[str] |
The tags stored on the row (at most 32). |
file_paths |
list[str] |
File paths stored on the row: the ones sent plus those found in the input and narrative; empty for a self-referential call. |
content_sha256 |
str |
Hash of the stored observation value (kind, tool, narrative, paths, error). |
tool_name |
str |
What the row holds, on the ledger as out_tool_name / out_has_error / out_narrative_chars — an observation with a 40-char narrative is a tool name, not an observation. |
has_error |
bool |
True when error was non-empty (always False for a self-referential call). |
narrative_chars |
int |
Length of the stored narrative in characters (at most 2000). |
skipped_reason |
str |
Why the row was stored content-less: "self_referential" (the tool was loom itself or a harness meta tool), "blacklisted" (the content matched a blacklist pattern); "" otherwise. |