Display object, field and view links as chips in the AI chat (#23573)
<img width="3840" height="1876" alt="CleanShot 2026-07-30 at 15 37 46@2x" src="https://github.com/user-attachments/assets/9fe178b9-c2fa-4b05-9c9d-0cdc80270b67" /> https://github.com/user-attachments/assets/34c4e486-c462-4300-ae98-da99f614f069 The AI chat already renders record chips from a `[[record:...]]` marker the model writes in its prose, but naming an object, field or view produced plain text. This adds three sibling markers so those render as chips too, as in the [Figma design](https://www.figma.com/design/xt8O9mFeLl46C5InWwoMrN/Twenty?node-id=104416-116261). - `[[object:<nameSingular>:<label>[[/object]]` links to the record index page. It is name-keyed rather than id-keyed so an object the assistant only *proposes* to create still renders as a chip, just without a link. - `[[field:<id>:<label>[[/field]]` links to the field's settings page, gated on the `DATA_MODEL` permission. - `[[view:<id>:<label>[[/view]]` links to the object index page for that view. Field and view ids must come from a tool, so an unresolvable one falls back to plain text rather than a chip that goes nowhere. The record-only parser becomes one scan over all four kinds. Alternative order is load-bearing: `[[view:<uuid>:` is shaped exactly like the legacy prefix-less record marker, so metadata kinds are tried first and only records keep the legacy `]]` terminator. Server side is prompt-only. The metadata and view tools return bare objects rather than `ToolOutput`, so there is nowhere to hang a structured reference array without wrapping every factory, and the names and ids the markers need are already in those results verbatim. Also fixes a pre-existing issue in `LazyMarkdownRenderer`: its `components` map was rebuilt on every render, and react-markdown uses each entry as the JSX element type, so every node remounted on every streamed chunk. Harmless before, expensive once the model is told to chip every metadata name it writes. <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/23573?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. -->
This commit is contained in:
+20
-1
@@ -85,5 +85,24 @@ Record References - IMPORTANT:
|
||||
- The recordId MUST be a real UUID (like "abc12345-1234-5678-abcd-123456789012")
|
||||
- DO NOT create record references before calling the tool
|
||||
- DO NOT use placeholder IDs like "rec-snowflake" or "rec-person-1"
|
||||
- If a tool hasn't been called yet, don't reference records that don't exist`,
|
||||
- If a tool hasn't been called yet, don't reference records that don't exist
|
||||
|
||||
Metadata References:
|
||||
Whenever you name an object, a field, or a view in your prose, write it as a metadata reference instead of plain text. Each one becomes a chip the user can click.
|
||||
|
||||
- Object: [[object:objectNameSingular:displayName[[/object]]
|
||||
- Example: [[object:company:Companies[[/object]]
|
||||
- Use the \`nameSingular\` from \`get_object_metadata\` or \`create_object_metadata\` (NOT the label, NOT the plural, NOT the id)
|
||||
- This is the only reference you may write for something that does not exist yet: when you propose creating an object, reference it with the \`nameSingular\` you intend to use and it renders as a chip without a link
|
||||
- Field: [[field:fieldMetadataId:displayName[[/field]]
|
||||
- Example: [[field:abc12345-1234-5678-abcd-123456789012:Annual Recurring Revenue[[/field]]
|
||||
- Use the \`id\` returned by \`get_field_metadata\`, \`create_field_metadata\`, or the \`fields\` array of \`get_object_metadata\`
|
||||
- View: [[view:viewId:displayName[[/view]]
|
||||
- Example: [[view:abc12345-1234-5678-abcd-123456789012:All Companies[[/view]]
|
||||
- Use the \`id\` returned by \`get_views\`, \`create_view\`, or \`upsert_complete_view\`
|
||||
|
||||
- The displayName is what the user reads, so use the human-readable label ("Annual Recurring Revenue"), not the technical name
|
||||
- Field and view ids MUST be real UUIDs copied from a tool response - never invent one, and never reference a field or view before the tool that returns it has run
|
||||
- Always close a reference with its own tag: \`[[/object]]\`, \`[[/field]]\`, \`[[/view]]\`. A mismatched closing tag drops the chip
|
||||
- Use metadata references only in paragraphs, lists, or markdown tables (\`| ... |\`); never in headings, code, links, or raw HTML`,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user