Skip to content

Commit a3b1862

Browse files
authored
refactor: rename SymAiContext child element classes with prefix (#424)
* refactor: rename SymAiContext child element classes with prefix - Rename Stream to SymAiContextStream - Rename Message to SymAiContextMessage - Rename Attachment to SymAiContextAttachment - Add optional from and to timestamp attributes to SymAiContextStream - Add comprehensive Javadoc documentation to all SymAiContext-related classes * chore: bump version to 1.4.0 * docs: add AI agent rules to prevent tool mentions in commits * Bumped pom.xml to 1.4.0
1 parent 9e3f138 commit a3b1862

File tree

9 files changed

+365
-136
lines changed

9 files changed

+365
-136
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>org.finos.symphony.messageml</groupId>
88
<artifactId>messageml-utils</artifactId>
9-
<version>1.3.0</version>
9+
<version>1.4.0</version>
1010
<name>MessageML Utils</name>
1111
<url>https://github.com/finos/messageml-utils</url>
1212
<description>A set of utilities for parsing, processing and rendering of MessageML messages

src/main/java/org/finos/symphony/messageml/messagemlutils/MessageMLParser.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import org.finos.symphony.messageml.messagemlutils.bi.BiContext;
1919
import org.finos.symphony.messageml.messagemlutils.bi.BiFields;
2020
import org.finos.symphony.messageml.messagemlutils.bi.BiItem;
21-
import org.finos.symphony.messageml.messagemlutils.elements.Attachment;
21+
import org.finos.symphony.messageml.messagemlutils.elements.SymAiContextAttachment;
2222
import org.finos.symphony.messageml.messagemlutils.elements.Bold;
2323
import org.finos.symphony.messageml.messagemlutils.elements.BulletList;
2424
import org.finos.symphony.messageml.messagemlutils.elements.Button;
@@ -69,8 +69,8 @@
6969
import org.finos.symphony.messageml.messagemlutils.elements.Subscript;
7070
import org.finos.symphony.messageml.messagemlutils.elements.Superscript;
7171
import org.finos.symphony.messageml.messagemlutils.elements.SymAiContext;
72-
import org.finos.symphony.messageml.messagemlutils.elements.Stream;
73-
import org.finos.symphony.messageml.messagemlutils.elements.Message;
72+
import org.finos.symphony.messageml.messagemlutils.elements.SymAiContextStream;
73+
import org.finos.symphony.messageml.messagemlutils.elements.SymAiContextMessage;
7474
import org.finos.symphony.messageml.messagemlutils.elements.Table;
7575
import org.finos.symphony.messageml.messagemlutils.elements.TableBody;
7676
import org.finos.symphony.messageml.messagemlutils.elements.TableCell;
@@ -498,14 +498,14 @@ public Element createElement(org.w3c.dom.Element element, Element parent) throws
498498
case SymAiContext.MESSAGEML_TAG:
499499
return new SymAiContext(parent, ++index);
500500

501-
case Stream.MESSAGEML_TAG:
502-
return new Stream(parent);
501+
case SymAiContextStream.MESSAGEML_TAG:
502+
return new SymAiContextStream(parent);
503503

504-
case Message.MESSAGEML_TAG:
505-
return new Message(parent);
504+
case SymAiContextMessage.MESSAGEML_TAG:
505+
return new SymAiContextMessage(parent);
506506

507-
case Attachment.MESSAGEML_TAG:
508-
return new Attachment(parent);
507+
case SymAiContextAttachment.MESSAGEML_TAG:
508+
return new SymAiContextAttachment(parent);
509509

510510
case Bold.MESSAGEML_TAG:
511511
return new Bold(parent);

src/main/java/org/finos/symphony/messageml/messagemlutils/elements/Attachment.java

Lines changed: 0 additions & 42 deletions
This file was deleted.

src/main/java/org/finos/symphony/messageml/messagemlutils/elements/Message.java

Lines changed: 0 additions & 39 deletions
This file was deleted.

src/main/java/org/finos/symphony/messageml/messagemlutils/elements/Stream.java

Lines changed: 0 additions & 39 deletions
This file was deleted.

src/main/java/org/finos/symphony/messageml/messagemlutils/elements/SymAiContext.java

Lines changed: 82 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,88 @@
55
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
66
import com.fasterxml.jackson.databind.node.ObjectNode;
77
import org.finos.symphony.messageml.messagemlutils.exceptions.InvalidInputException;
8-
import org.commonmark.node.Node;
9-
import org.commonmark.node.Paragraph;
108

119
import org.finos.symphony.messageml.messagemlutils.util.XmlPrintStream;
1210

1311
import java.util.Arrays;
1412
import java.util.List;
1513

14+
/**
15+
* Represents the {@code <sym-ai-context>} element in MessageML.
16+
*
17+
* <p>This element provides context information for Symphony AI features by grouping references
18+
* to streams, messages, and attachments. It is a beta feature and can only be used when the
19+
* root {@code <messageML>} element has the {@code beta="true"} attribute set.</p>
20+
*
21+
* <h3>Allowed Children</h3>
22+
* <ul>
23+
* <li>{@link SymAiContextStream} - References to conversation streams</li>
24+
* <li>{@link SymAiContextMessage} - References to specific messages</li>
25+
* <li>{@link SymAiContextAttachment} - References to file attachments</li>
26+
* </ul>
27+
*
28+
* <h3>Example Usage</h3>
29+
* <pre>{@code
30+
* <messageML beta="true">
31+
* <sym-ai-context>
32+
* <sym-ai-stream id="streamId123" from="1707235200000" to="1707321600000"/>
33+
* <sym-ai-message id="msgId456"/>
34+
* <sym-ai-attachment streamId="streamId123" messageId="msgId456" fileId="fileId789"/>
35+
* </sym-ai-context>
36+
* Please summarize the conversation.
37+
* </messageML>
38+
* }</pre>
39+
*
40+
* <h3>Entity JSON Output</h3>
41+
* <p>The element generates an entity JSON structure with arrays for messages, streams, and attachments:</p>
42+
* <pre>{@code
43+
* {
44+
* "sym-ai-context1": {
45+
* "type": "com.symphony.ai.context",
46+
* "version": "1.0",
47+
* "messages": [{"id": "msgId456"}],
48+
* "streams": [{"id": "streamId123", "from": "1707235200000", "to": "1707321600000"}],
49+
* "attachments": [{"id": "fileId789", "streamId": "streamId123", "messageId": "msgId456"}]
50+
* }
51+
* }
52+
* }</pre>
53+
*
54+
* @see SymAiContextStream
55+
* @see SymAiContextMessage
56+
* @see SymAiContextAttachment
57+
*/
1658
public class SymAiContext extends Entity {
1759
public static final String MESSAGEML_TAG = "sym-ai-context";
1860
public static final String ENTITY_TYPE = "com.symphony.ai.context";
1961
private static final String ENTITY_VERSION = "1.0";
2062
private static final String ENTITY_SUBTYPE = "com.symphony.ai.contextId";
2163

22-
private static final List<String> ALLOWED_CHILDREN = Arrays.asList(Stream.MESSAGEML_TAG, Message.MESSAGEML_TAG, Attachment.MESSAGEML_TAG);
64+
private static final List<String> ALLOWED_CHILDREN = Arrays.asList(SymAiContextStream.MESSAGEML_TAG, SymAiContextMessage.MESSAGEML_TAG, SymAiContextAttachment.MESSAGEML_TAG);
2365

66+
/**
67+
* Constructs a new SymAiContext element.
68+
*
69+
* @param parent the parent element in the MessageML tree
70+
* @param entityIndex the index used to generate a unique entity ID
71+
*/
2472
public SymAiContext(Element parent, int entityIndex) {
2573
super(parent, MESSAGEML_TAG, Entity.DEFAULT_PRESENTATIONML_TAG, FormatEnum.MESSAGEML);
2674
this.entityId = getEntityId(entityIndex);
2775
}
2876

77+
/**
78+
* Validates the SymAiContext element.
79+
*
80+
* <p>This method checks that:</p>
81+
* <ul>
82+
* <li>The root {@code <messageML>} element has {@code beta="true"}</li>
83+
* <li>The element contains no direct text content</li>
84+
* <li>All child elements are one of the allowed types: {@code <sym-ai-stream>},
85+
* {@code <sym-ai-message>}, or {@code <sym-ai-attachment>}</li>
86+
* </ul>
87+
*
88+
* @throws InvalidInputException if validation fails
89+
*/
2990
@Override
3091
public void validate() throws InvalidInputException {
3192
// Check if root MessageML has beta="true"
@@ -58,6 +119,15 @@ private MessageML getRoot() {
58119
return (current instanceof MessageML) ? (MessageML) current : null;
59120
}
60121

122+
/**
123+
* Generates the entity JSON representation for this context element.
124+
*
125+
* <p>The generated JSON contains arrays for messages, streams, and attachments,
126+
* populated from the child elements of this context.</p>
127+
*
128+
* @param parent the parent JSON object to add this entity to
129+
* @return the JSON node representing this entity
130+
*/
61131
@Override
62132
public ObjectNode asEntityJson(ObjectNode parent) {
63133
ObjectNode node = new ObjectNode(JsonNodeFactory.instance);
@@ -70,17 +140,23 @@ public ObjectNode asEntityJson(ObjectNode parent) {
70140

71141
for(Element child: getChildren()) {
72142
switch (child.getMessageMLTag()) {
73-
case Message.MESSAGEML_TAG:
143+
case SymAiContextMessage.MESSAGEML_TAG:
74144
ObjectNode messageObj = new ObjectNode(JsonNodeFactory.instance);
75145
messageObj.put("id", child.getAttribute("id"));
76146
messageNode.add(messageObj);
77147
break;
78-
case Stream.MESSAGEML_TAG:
148+
case SymAiContextStream.MESSAGEML_TAG:
79149
ObjectNode streamObj = new ObjectNode(JsonNodeFactory.instance);
80150
streamObj.put("id", child.getAttribute("id"));
151+
if (child.getAttribute("from") != null) {
152+
streamObj.put("from", child.getAttribute("from"));
153+
}
154+
if (child.getAttribute("to") != null) {
155+
streamObj.put("to", child.getAttribute("to"));
156+
}
81157
streamNode.add(streamObj);
82158
break;
83-
case Attachment.MESSAGEML_TAG:
159+
case SymAiContextAttachment.MESSAGEML_TAG:
84160
ObjectNode attachmentObj = new ObjectNode(JsonNodeFactory.instance);
85161
attachmentObj.put("id", child.getAttribute("fileId"));
86162
attachmentObj.put("streamId", child.getAttribute("streamId"));
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
2+
package org.finos.symphony.messageml.messagemlutils.elements;
3+
4+
import org.commonmark.node.Text;
5+
import org.finos.symphony.messageml.messagemlutils.MessageMLParser;
6+
import org.finos.symphony.messageml.messagemlutils.exceptions.InvalidInputException;
7+
import org.commonmark.node.Node;
8+
9+
/**
10+
* Represents the {@code <sym-ai-attachment>} element in MessageML.
11+
*
12+
* <p>This element references a file attachment within a {@link SymAiContext}.
13+
* It allows AI features to access and process attachments by specifying the stream,
14+
* message, and file identifiers.</p>
15+
*
16+
* <h3>Attributes</h3>
17+
* <ul>
18+
* <li>{@code streamId} (optional) - The identifier of the stream containing the attachment</li>
19+
* <li>{@code messageId} (optional) - The identifier of the message containing the attachment</li>
20+
* <li>{@code fileId} (optional) - The unique identifier of the file attachment</li>
21+
* </ul>
22+
*
23+
* <h3>Example Usage</h3>
24+
* <pre>{@code
25+
* <sym-ai-attachment streamId="streamId123" messageId="msgId456" fileId="fileId789"/>
26+
* }</pre>
27+
*
28+
* <p>This element must be a child of {@link SymAiContext} and cannot contain any content.</p>
29+
*
30+
* @see SymAiContext
31+
*/
32+
public class SymAiContextAttachment extends Element {
33+
/** The MessageML tag name for this element. */
34+
public static final String MESSAGEML_TAG = "sym-ai-attachment";
35+
private static final String ATTR_STREAM_ID = "streamId";
36+
private static final String ATTR_MESSAGE_ID = "messageId";
37+
private static final String ATTR_FILE_ID = "fileId";
38+
39+
/**
40+
* Constructs a new SymAiContextAttachment element.
41+
*
42+
* @param parent the parent element in the MessageML tree
43+
*/
44+
public SymAiContextAttachment(Element parent) {
45+
super(parent, MESSAGEML_TAG);
46+
}
47+
48+
/**
49+
* {@inheritDoc}
50+
*/
51+
@Override
52+
protected void buildAttribute(MessageMLParser parser, org.w3c.dom.Node item) throws InvalidInputException {
53+
switch (item.getNodeName()) {
54+
case ATTR_STREAM_ID:
55+
case ATTR_MESSAGE_ID:
56+
case ATTR_FILE_ID:
57+
setAttribute(item.getNodeName(), getStringAttribute(item));
58+
break;
59+
default:
60+
super.buildAttribute(parser, item);
61+
}
62+
}
63+
64+
/**
65+
* Validates the SymAiContextAttachment element.
66+
*
67+
* <p>This method ensures that the element has no content (text or child elements).</p>
68+
*
69+
* @throws InvalidInputException if validation fails
70+
*/
71+
@Override
72+
public void validate() throws InvalidInputException {
73+
assertNoContent();
74+
}
75+
76+
/**
77+
* Returns the Markdown representation of this element.
78+
*
79+
* <p>Generates a text representation showing the attachment identifiers in the format:
80+
* {@code Attachment(streamId=..., messageId=..., fileId=...)}</p>
81+
*
82+
* @return a Text node containing the attachment information
83+
*/
84+
@Override
85+
public Node asMarkdown() {
86+
return new Text(String.format("Attachment(streamdId=%s, messageId=%s, fileId=%s)", getAttribute(ATTR_STREAM_ID), getAttribute(ATTR_MESSAGE_ID), getAttribute(ATTR_FILE_ID)));
87+
}
88+
}

0 commit comments

Comments
 (0)