Open pierreneu opened 2 years ago
This seems like a use-case that others would run into (wanting to provide additional, optional metadata about an interaction). Wrapping context types to do this does indeed break the coupling between apps (which is based on specific intent/context type pairs) and adding the metadata into context types affects any that you use (including non-standard proprietary types) and does not seem practical.
Hence (as discussed off to the side), what I'd propose is that we extend ContextMetadata so this can contain some additional fields (we wrapped the only field it currently carries, AppIdentifier
, in ContextMetadata
for exactly this sort of future-proofing). We could then extend other functions with a new optional argument to include that metadata, e.g.
broadcast(context: Context): Promise<void>;
changes to:
broadcast(context: Context, sourceMetadata?: Context): Promise<void>;
raiseIntent(intent: string, context: Context, app?: AppIdentifier): Promise<IntentResolution>;
changes to:
raiseIntent(intent: string, context: Context, app?: AppIdentifier, sourceMetadata?: Context): Promise<IntentResolution>;
and ContextMetadata
changes from:
interface ContextMetadata {
/** Identifier for the app instance that sent the context and/or intent.
* @experimental
*/
readonly source: AppIdentifier;
}
to
interface ContextMetadata {
/** Identifier for the app instance that sent the context and/or intent.
* @experimental
*/
readonly source: AppIdentifier;
/** Additional optional metadata that an app may choose to send with a broadcast context or raised intent.
* For example to provide source information from within the source application (e.g. from which chat room
* (in a chat app) or order (in an OMS) did the message originate from.
* @experimental
*/
readonly sourceMetadata: Context;
}
You could then pass in your ChatRoom context as the sourceMetadata
.
ContextMetadata/Originating app metadata is currently an optional feature (there is an issue open to consider whether that should be required, see https://github.com/finos/FDC3/issues/735). But it looks like adding this wouldn’t break anything and could make it more useful… The additional §sourceMetadata§ would become available but the interaction is not dependent on it - making it optional.
However, it is an API change so it’d have to happen in an FDC3 2.1…
+1 on this as a concept. Especially useful for case Pierre mentioned whereby downstream systems can pick up chat IDs for subsequent messaging but I can see it being useful in other situations as well.
It's not really clear from the description exactly what the use case is here. It just says that there might be extra data useful to the receiving app. It would be really handy to have an exact example of this so that I can think about it the same way. At the moment, I am wondering a bit why a charting application would want to know anything about chat rooms, for instance.
Leaving aside any changes to FDC3, I think this is what you could do at the moment:
setup
ViewInstrument
intent for a fdc3.instrument
context. PublishToChat
intent for the fdc3.chart
context.in action
user wants to turn a ticker into a chart and publish that chart into a chat room
fdc3.chat.initSettings
that the user is currently in, as the user navigates between chats.ViewInstrument
intent, with the fdc3.instrument
context for that ticker. PublishToChat
intent, which uses the fdc3.chart
and also the last broadcast fdc3.chat.initSettings
context.There are a few problems with this:
PublishToChat
is going to do different things depending on which chat you're looking at when you call it.Am I on the right track understanding this?
@robmoffat @pierreneu - picking this thread up again (sorry for the long delay). You are on the right track.
I think the way to describe the proposal is: when broadcasting a context or raising an intent/context pair, you should be able to attach an additional context that represents a source or similar reference for it. This reference may be used for a secondary purpose such as logging or taking follow-up actions.
Re: the @robmoffat foresaw:
First, symphony is going to be broadcasting chat/room contexts information a lot. I'm not entirely sure this is a bad thing, since it would let other applications know which chat the user is engaged with.
Second, there is no linkage from the chat room to the instrument, so you don't necessarily know if the instrument is coming from the latest broadcast chat.
type ContextHandler = (context: Context, metadata?: ContextMetadata) => void;
type IntentHandler = (context: Context, metadata?: ContextMetadata) => Promise<IntentResult> | void;
interface ContextMetadata {
readonly source: AppIdentifier;
readonly sourceMetadata: Context; //<- this is the proposed new bit
}
Third, the latest broadcast chat might change while you're viewing the instrument in ChartIQ. So, PublishToChat is going to do different things depending on which chat you're looking at when you call it.
The metadata is tied to a specific broadcast, rather than a channel. Hence, if you want the sourceMetadata
for a specific past message, you need to keep hold of it, rather than using whatever was the most recent one.
I think this is interesting because it adds a bit more (optional) nuance to context messages that can make follow-up actions easier/better.
I disagree with this proposal for the following reasons:
fdc3.instrument
there was metadata X
, and so when I call an intent, I also need to supply metadata X
going back again. Which seems like an imposition on other apps.I'm going to suggest different solutions to each of these in turn.
In actual fact I think there are lots of use cases which are similar to this that aren't supported by FDC3 and wouldn't be covered by this solution anyway. For example:
counterparty
books a trade
which changes aposition
on a given instrument
contact
posts a chart
in a chat room
In both of these, there are multiple pieces of context data for the same event.
I think it would make more sense if the ContextMetadata
could contain some kind of optional, app-supplied eventId
which would allow other apps listening to a channel to correlate context data back into the event they came from, if this was needed:
Rather than ChartIQ being expected to handle the context data linking, Symphony could do it if It wants to. That is - it should be aware of the fact that an intent was raised in a given room with a given instrument. Since the Chart
context item coming back also contains the same instrument it could figure out which room raised the chart in the first place.
But actually I think this is the simplest solution to the problem - just providing a picker list of chats with the most recent ones the user has engaged in being first on the list.
(n.b. attempting to clarify the proposal here, not advocating for it)
@robmoffat Re: your issues 1&2, i think the easiest way to understand this is that the existing context is all you ever need for the initial action and the metadata can 100% be ignored. In your examples:
A counterparty books a trade which changes a position on a given instrument A contact posts a chart in a chat room
All of this data would go in the 'primary' or existing context argument:
order
context, that embeds an instrument
and counterparty
. The position
is updated later after the trade
happens (trade
might be returned as a result, but probably happens later)message
, chat room
, and any attachments. I.e. I don't think these examples are affected by the proposal - but they are a good reminder that the design of contexts is important and that they should contain at least the minimum required detail for follow-up actions/responses from the resolving application..
Re: issues 3 & 4 - I don't think any sort of contract needs to be honoured. Rather the metadata could be used to inform a secondary action such as a reply. As you state, there are other ways that could be dealt with such as interaction history in the chat application and the user could/should absolutely be given control.
To sum up, I see this proposal as trying to provide some additional contextual information on the action/raised intent coming from the first application so that it can be used to better formulate or direct a response back from the second application.
As you point out, there are ways that the first application could itself try to internally direct or handle the response it receives from the second application using its own records (which could include recent chats, which apps resolved intents it sent outwards etc.) - although perhaps with a bit less precision.
I know we'll receive feedback that this adds complexity to FDC3 - which is fair. It might reduce complexity in apps that need this feature - but I doubt that will be enough of a sue case to see it approved.
An entirely alternative approach that could be used is to make no changes to the API at all, and instead add a sourceContext or similar element to individual context types or even Context itself (so all inherit it, as optional) to encourage including the desired source info in the primary context.
P.S. thanks for your analysis on this one @robmoffat - has certainly helped me come to a conclusion on how I feel about it!
@pierreneu @nemery-flextrade Let us know if you get a chance to review this and have thoughts on the alternative proposal (add something to the primary context if you want to provide source metadata).
@kriswest said:
In the first one you might have an order context, that embeds an instrument and counterparty. The position is updated later after the trade happens (trade might be returned as a result, but probably happens later)
Yes, but that's the point. If I am an application just listening for instruments, then the instrument embedded in the order context wouldn't come to me.
Sometimes, that behaviour might be good. Other times (like, I think, in the examples I give) it would be better if it were possible to be able to subscribe to context items individually.
For channels, you can subscribe to the individual types and the advice is for the app sharing context to broadcast all the different types you might want other apps to bind onto (see https://fdc3.finos.org/docs/api/spec#broadcasting-and-listening-for-multiple-context-types) - personally, I'm not a fan of this, and had an alternative proposal (and util function) for recursing through a context to find types you support and can act on - but the decision went the other way and picked something 'simpler' (which seems to actually create more complexity 😱).
For intents, it's a bit different as you can only send one thing. However, you can research the options before you do with findIntent
(although you have to call it with each type you could send as AppIntent
doesn't tell you what context is needed). That said, I think the use case is generally different for an intent as it's a specific action, rather than synchronization of context, and that will usually have specific data requirements for that action (although I can think of one counter-example, e.g. ViewChart with Chart or Instrument).
At any rate, I don't there's any suggestion that the proposed additional data should ever be needed to perform a requested action - only ever inform later subsidiary actions (logging, responses etc.).
If anything were to be done about this particular issue, I think it would need further advocacy and use cases from a number of participants.
As for your thoughts on extracting embedded contexts - great minds think alike ;-). I think it a separate issue, however.
Question Area
[ ] App Directory [ ] API [X] Context Data [X] Intents [ ] Use Cases [ ] Other
Question
Right now Symphony raises intents such as ViewInstrument, with a
fdc3.instrument
context, allowing the action to be performed in another app that is configured to handle that intent and context pair.However, we'd like to include more information (metadata about the interaction) in the context data, such as the chat room id, message id, user email/id etc. as this might be useful to the receiving app. However, adding it to the instrument object is not semantically correct (it doesn't relate to the instrument.
This additional metadata might be added not only to the ViewInstrument intent, but any outgoing intents coming from out application.
Options we think of:
ContextMetadata
that the receiving app MAY receive (Originating App Metadata).ContextMetadata
is currently supplied by the Desktop Agent, we would need a way to supply additional information to the Desktop Agent to augment it.Based on a side discussion with Kris, it seems that the current standard may not provide a perfect solution.