Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add Metadata Update Flow Control and New State for Connection Monitoring #73

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

lotharking
Copy link
Contributor

@lotharking lotharking commented Jan 28, 2025

Summary

A concurrency issue was detected when starting the chatbot flow, beginning with the profile submission as specified in the specifications. This issue occurred because the sending of the capabilities was delayed compared to the sending of the profiles with the language, which led to a lack of a clear starting point for the chatbot flow controlled by the NestJS library.

The need to add a new state called "Updated" to the ExtendedDidExchangeState was identified to address this. This state monitors updates to the metadata. This state aims to send the necessary updates to inform the chatbots that the connection contains relevant and useful information.

With this new state in place, we can now monitor when the connection is updated, and use this update as an indication of a new connection. This allows the user to map the connection according to their specific interests.

Changes

  • Added new state to ExtendedDidExchangeState: Introduced a new state to track connection updates.
  • Added metadata flow control by updated: Implemented flow control to monitor metadata updates.
  • Created updateMetadata method: Developed a method to update metadata as needed
  • Created isCompleted method for complete validation: Added a method to validate if the connection has been completed after save capabilities and profile.
  • Added flow control by ExtendedDidExchangeState.Updated: Implemented flow control based on the new "Updated" state in ExtendedDidExchangeState.

Related Issues

Testing

Checklist

  • I have commented on my code, especially in areas that are hard to understand.
  • I have added only changes relevant to the issue in question.
  • I have added tests to confirm that my fix is effective or that my feature works as intended.
  • I have modified existing tests as needed to accommodate my changes.
  • I have flagged specific areas for further review, if necessary.
  • I have updated the documentation where necessary.

@lotharking lotharking changed the title fix: send profile feat: Add Metadata Update Flow Control and New State for Connection Monitoring Jan 28, 2025
@lotharking lotharking marked this pull request as ready for review January 28, 2025 22:20
@lotharking lotharking requested a review from genaris January 28, 2025 22:20
@@ -454,6 +457,14 @@ export const messageEvents = async (agent: ServiceAgent, config: ServerConfig) =
})

await sendMessageReceivedEvent(agent, msg, msg.timestamp, config)

const body = new ConnectionStateUpdated({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the code base like it is right now, I don't see why are we generating such a new webhook event, since we can catch the data from the ProfileMessage message-received-event. Also, it would not be completely correct to generate a connection-state-update, since we are not actually updating the connection itself within Service Agent's main module (no actual ConnectionRecord metadata is being updated).

Is there any reason why you cannot hook into message received event to process this user profile? If so, would it make sense to create a new webhook event specific for user profile? I propose this thinking on the future, since we want to get rid of current Service Agent main API and if we want to use Credo core directly, we'll get different events for each situation (one for connection metadata updated, another for user profile received).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each event is handled independently, and the start state is used. A connection is not considered completed until the capabilities and profile have been validated

@@ -14,7 +14,7 @@ export class ConnectionEntity {
status?: ExtendedDidExchangeState

@Column({ type: 'varchar', nullable: true })
language?: string
lang?: string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be a lot better if, instead of having a plain field with this single element, you could store the whole User Profile here. This way you can store user's display picture, display name and other stuff that could be useful for client apps.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added new userProfile

@@ -14,7 +14,7 @@ export class ConnectionEntity {
status?: ExtendedDidExchangeState

@Column({ type: 'varchar', nullable: true })
language?: string
lang?: string

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More on this: what about creating a specific field for features, which will contain an object with all capabilities, protocols, etc. discovered? This could make nestjs-client a bit more friendly to manage.

Copy link
Contributor Author

@lotharking lotharking Jan 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By making good use of the metadata field, I would consider it unnecessary to create a further breakdown, as it currently allows the user to use all the values of the capabilities regardless of their structure.
This proposal would be good to implement, but perhaps standardizing the capabilities in the models would be better. However, since the capabilities are being added to Credo, it might be best to wait until they are standardized.
user profile created for handling params

if (!conn?.createdTs) {
throw new Error(`No connection found with id: ${id}. The connection may not have been created properly`)
}
const { lang, metadata, createdTs } = conn
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find this logic far more complicated (and maybe not as stable) as it could if we'd manage user profile and features in separate events and database fields.

@lotharking lotharking requested a review from genaris January 30, 2025 22:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants