Skip to content

Conversation

rahul-madaan
Copy link
Contributor

@rahul-madaan rahul-madaan commented Sep 16, 2025

This PR adds a new tool get_asset_history for the following usecases

Tested for prompts like:
"when was the description updated and who updated it for x asset?"
"who was the owner of this x asset on y date"
"what was the description of this asset before it was last updated?"
"who changes the description from x to y for z asset?"

Screenshot 2025-09-18 at 11 20 51 PM Screenshot 2025-09-18 at 11 22 36 PM Screenshot 2025-09-18 at 11 24 25 PM Screenshot 2025-09-18 at 11 26 28 PM Screenshot 2025-09-18 at 11 26 53 PM

Copy link
Collaborator

@Hk669 Hk669 left a comment

Choose a reason for hiding this comment

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

also please check the merge conflicts, i can test it locally post that.

Comment on lines 217 to 264
"count": len(entity_audits),
"totalCount": response.total_count,
Copy link
Collaborator

Choose a reason for hiding this comment

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

what is the difference between count and totalCount?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Count is the number of audit entries that are now being sent by the MCP, which should be actually equal to the number of entries requested by the user in the request. And total_count is the total number of entries that can be obtained from Atlas.

@rahul-madaan rahul-madaan requested a review from Hk669 September 22, 2025 15:55
Copy link
Member

@firecast firecast left a comment

Choose a reason for hiding this comment

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

Please make changes to the doc as well

guid=None, qualified_name=None, type_name=None, size=10, sort_order="DESC"
):
"""
Get the audit history of an asset by GUID or qualified name.
Copy link
Member

Choose a reason for hiding this comment

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

Lets add information about how does the LLM fetch the guid or qualified name of the asset. Also this should be Get the audit history of an asset by GUID or qualified name/typename.

Copy link
Member

Choose a reason for hiding this comment

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

Also do we need to support qualifiedname/typename or just guid should be enough?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I believe guid should be enough because there would be a very rare case when customer directly provides qualifiedname/typename and even if they do, claude can make search call to find the guid.

I will remove this.

Returns:
Dict[str, Any]: Dictionary containing:
- entityAudits: List of audit entries with details about each change
Copy link
Member

Choose a reason for hiding this comment

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

can we follow a proper pattern. The argument names are snake case but dictionary keys are camelcase

request = create_audit_search_request(
guid, qualified_name, type_name, size, sort_item
)
response = client.audit.search(criteria=request, bulk=False)
Copy link
Member

Choose a reason for hiding this comment

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

We should catch exceptions and return them as errors since you have defined the tool in that way

Copy link
Contributor Author

Choose a reason for hiding this comment

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

exception handling is properly implemented here, it is in try catch block.

- errors: List of any errors encountered
Raises:
Exception: If there's an error retrieving the asset history
Copy link
Member

Choose a reason for hiding this comment

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

DOes it raise exceptions?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes

Copy link
Contributor Author

Choose a reason for hiding this comment

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

in cases when API key does not have enough permissions.

client = get_atlan_client()

# Create sort item
sort_item = create_sort_item(sort_order)
Copy link
Member

Choose a reason for hiding this comment

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

Do we need separate functions for these?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no, I will remove this.

Either guid or qualified_name must be provided.
type_name (str, optional): Type name of the asset (required when using qualified_name).
Examples: "Table", "Column", "DbtModel", "AtlasGlossary"
size (int): Number of history entries to return. Defaults to 10.
Copy link
Member

Choose a reason for hiding this comment

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

Add a max size value

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Dictionary with basic audit information
"""
return {
"entityQualifiedName": getattr(result, "entity_qualified_name", None),
Copy link
Member

Choose a reason for hiding this comment

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

Do we need to send qf, guid, typename? considering we are fetching it for that entity only. It will just use up token

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removing qf and typename

"timestamp": getattr(result, "timestamp", None),
"action": getattr(result, "action", None),
"user": getattr(result, "user", None),
"created": getattr(result, "created", None),
Copy link
Member

Choose a reason for hiding this comment

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

Lets remove created as well

"""
try:
# Extract basic audit information
audit_entry = extract_basic_audit_info(result)
Copy link
Member

Choose a reason for hiding this comment

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

Move this to the main function only


return audit_entry

except Exception as e:
Copy link
Member

Choose a reason for hiding this comment

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

When will this exception be raised?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, I checked it is all handled. I will remove this.

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.

3 participants