Skip to content

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.