Agent instructions: Store recipes and entity types

← Agent instructions

Store recipes

Use only the recipes below. MUST NOT list, glob, or read MCP tool descriptor or schema files for chat, attachment, or entity-extraction flows. Tool parameters: store_structured(entities, idempotency_key, relationships, file_path|file_content+mime_type, file_idempotency_key?) and create_relationship(relationship_type, source_entity_id, target_entity_id). Response IDs come back as structured.entities[].entity_id and unstructured.asset_entity_id.

  • Relationship batching. When related entities are created in the same call, define ALL their links via the relationships array using { relationship_type, source_index, target_index } entries. Do not issue one create_relationship call per link when batching is possible.
  • Turn identity. Use host conversation and turn ids when available. If absent, build a synthetic conversation_id (never a generic prefix like cursor alone) plus a turn index/timestamp; set turn_key = "{conversation_id}:{turn_id}" and a unique idempotency_key. Unscoped turn keys cause cross-conversation entity collisions.
  • Fallback IDs. When the host gives no ids at all, use idempotency_key "conversation-chat-<turn>-<timestamp_ms>" and turn_key "chat:<turn>".
  • observation_source. Optional flag describing the kind of write, sensor (deterministic tool/telemetry), workflow_state (state-machine transitions), llm_summary (the default; omit it for ordinary chat), human (direct edit/acceptance), or import (batch/ETL). Used as a tie-break after source_priority; one value applies to every observation produced by the request.

User-phase (one call per user message)

  • Shape. entities = [{ entity_type: "conversation", title? }, { entity_type: "conversation_message", role: "user", sender_kind: "user", content: "<exact message>", turn_key: "{conversation_id}:{turn_id}" }, …optional extracted entities]. Indices: 0 = conversation, 1 = message, 2+ = extracted. The legacy agent_message type is accepted as an alias and resolved to conversation_message for pre-v0.6 clients.
  • Relationships. Always PART_OF from message (1) to conversation (0). For every entity created OR updated this turn, add REFERS_TO from the message to that entity. Skip when the edge already exists.
  • Naming. Keep names human-readable. For conversation_message, set canonical_name to a concise summary; never use turn keys, raw ids, timestamps, or tool names as the primary label. For conversation, keep title topical and update only when the central topic materially changes.
  • Canonical-name scope. canonical_name is a short label, not a container for every detail. Put message body in content and extra semantics in fields like title, subject, summary, description, turn_key, role, status, etc.
  • Extraction. If the message implies an entity (purchase, task, event, person, place, etc.), append it with a descriptive entity_type and the properties the message implies, no fixed schema. Do not call list_entity_types before storing.
  • idempotency_key. conversation-{conversation_id}-{turn_id}-{suffix} or, on fallback, conversation-chat-<turn>-{suffix}.

Attachments (one call: file + entities together)

  1. Parse. PDFs go through parse_file; text/CSV/JSON/Markdown read directly; images use vision. If parsing yields no usable text, store the raw file only.
  2. Extract. One snake_case field per fact, no invention. Use a descriptive entity_type matching the document (receipt, invoice, note, contract, person, contact, company, task, event, transaction, etc.).
  3. Store. One store_structured with [conversation, user message, …extracted entities], idempotency key, relationships with PART_OF (message→conversation) and any REFERS_TO edges, plus file_path (resolve to absolute) or file_content + mime_type. Optional file_idempotency_key: "file-<short-slug>".
  4. EMBEDS. create_relationship(EMBEDS, user_message_id, asset_entity_id) using the ids returned by step 3.

Screenshots and images

Use the attachment recipe. Extract every distinct entity visible in the image (people, messages, dates, criteria, tasks, events, offers, transactions) before responding. Add PART_OF (message→conversation), REFERS_TO (message→each extracted entity), and EMBEDS (message→file entity).

Chat fallbacks

  • Overwriting between branches is acceptable; users can audit history via list_observations. For reverted turns, optionally call create_relationship(SUPERSEDES, new_message_id, previous_message_id).
  • When a client does not support inline relationships: call store_structured first, then create_relationship(PART_OF, message_id, conversation_id) and one REFERS_TO per extracted entity.

Entity types and schema

  • Schema-agnostic for chat. Use a descriptive entity_type and whatever properties the message implies; the server accepts arbitrary fields. Do not call list_entity_types before storing.
  • Type reuse. Before introducing a new type, check for semantic equivalents (singular vs plural, person/contact, social_post/social_media_post). Prefer the type with more existing entities; consult list_entity_types with a keyword search if the cached list is stale. FORBIDDEN: creating a new type when an equivalent exists.
  • Schema evolution. Use update_schema_incremental to add fields (minor bump) or remove fields via fields_to_remove (major bump). Removed fields are excluded from snapshots but observation data is preserved; re-adding restores them. At least one field must remain.
  • Existing-entity correction. When fixing inaccurate values or normalizing ad hoc fields into an established schema, use correct on the existing entity rather than creating a duplicate. Prefer canonical schema fields over ad hoc additions.
  • Type consistency in a workflow. Within one import or workflow, pick one canonical type and keep it consistent. For generic financial rows, default to transaction and store source-specific details as fields (provider, account_suffix, value_date, concept).
  • conversation_message sender semantics. Always set sender_kind (one of user, assistant, agent, system, tool) alongside the legacy role field. For agent-to-agent traffic, set sender_kind: "agent" with sender_agent_id and optional recipient_agent_id. For the parent conversation, set thread_kind to human_agent, agent_agent, or multi_party.