-
Notifications
You must be signed in to change notification settings - Fork 70
allow user to undo the actions done by ai agent #241
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| import { createMockApiClient } from './test-utils/mock-api-client'; | ||
| import { ChangeItemColumnValuesTool } from './change-item-column-values-tool'; | ||
|
|
||
| describe('ChangeItemColumnValuesTool', () => { | ||
| let mocks: ReturnType<typeof createMockApiClient>; | ||
|
|
||
| beforeEach(() => { | ||
| mocks = createMockApiClient(); | ||
| jest.clearAllMocks(); | ||
| }); | ||
|
|
||
| const successfulResponse = { | ||
| change_multiple_column_values: { | ||
| id: '123456789', | ||
| }, | ||
| }; | ||
|
|
||
| describe('with boardId in context', () => { | ||
| it('calls the mutation with correct variables including options.disable_undo=false', async () => { | ||
| mocks.setResponse(successfulResponse); | ||
|
|
||
| const tool = new ChangeItemColumnValuesTool(mocks.mockApiClient, 'fake_token', { boardId: 456 }); | ||
| const result = await tool.execute({ | ||
| itemId: 123, | ||
| columnValues: '{"text_column": "New Value"}', | ||
| }); | ||
|
|
||
| expect(result.content).toBe('Item 123456789 successfully updated with the new column values'); | ||
| expect(mocks.getMockRequest()).toHaveBeenCalledWith( | ||
| expect.stringContaining('mutation changeItemColumnValues'), | ||
| { | ||
| boardId: '456', | ||
| itemId: '123', | ||
| columnValues: '{"text_column": "New Value"}', | ||
| options: { disable_undo: false }, | ||
| }, | ||
| ); | ||
| }); | ||
| }); | ||
|
|
||
| describe('with boardId in input', () => { | ||
| it('calls the mutation with correct variables including options.disable_undo=false', async () => { | ||
| mocks.setResponse(successfulResponse); | ||
|
|
||
| const tool = new ChangeItemColumnValuesTool(mocks.mockApiClient, 'fake_token'); | ||
| const result = await tool.execute({ | ||
| boardId: 789, | ||
| itemId: 123, | ||
| columnValues: '{"status_column": {"label": "Done"}}', | ||
| }); | ||
|
|
||
| expect(result.content).toBe('Item 123456789 successfully updated with the new column values'); | ||
| expect(mocks.getMockRequest()).toHaveBeenCalledWith( | ||
| expect.stringContaining('mutation changeItemColumnValues'), | ||
| { | ||
| boardId: '789', | ||
| itemId: '123', | ||
| columnValues: '{"status_column": {"label": "Done"}}', | ||
| options: { disable_undo: false }, | ||
| }, | ||
| ); | ||
| }); | ||
| }); | ||
|
|
||
| it('propagates errors from the API', async () => { | ||
| mocks.setError('Something went wrong'); | ||
|
|
||
| const tool = new ChangeItemColumnValuesTool(mocks.mockApiClient, 'fake_token', { boardId: 456 }); | ||
|
|
||
| await expect( | ||
| tool.execute({ | ||
| itemId: 123, | ||
| columnValues: '{"text_column": "New Value"}', | ||
| }), | ||
| ).rejects.toThrow('Something went wrong'); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -99,7 +99,7 @@ type Documents = { | |
| "\n mutation DeleteItem($id: ID!) {\n delete_item(item_id: $id) {\n id\n }\n }\n": typeof types.DeleteItemDocument, | ||
| "\n mutation createItem($boardId: ID!, $itemName: String!, $groupId: String, $columnValues: JSON) {\n create_item(board_id: $boardId, item_name: $itemName, group_id: $groupId, column_values: $columnValues) {\n id\n name\n }\n }\n": typeof types.CreateItemDocument, | ||
| "\n query getBoardSchema($boardId: ID!) {\n boards(ids: [$boardId]) {\n groups {\n id\n title\n }\n columns {\n id\n type\n title\n }\n }\n }\n": typeof types.GetBoardSchemaDocument, | ||
| "\n mutation changeItemColumnValues($boardId: ID!, $itemId: ID!, $columnValues: JSON!) {\n change_multiple_column_values(board_id: $boardId, item_id: $itemId, column_values: $columnValues) {\n id\n }\n }\n": typeof types.ChangeItemColumnValuesDocument, | ||
| "\n mutation changeItemColumnValues($boardId: ID!, $itemId: ID!, $columnValues: JSON!, $options: JSON) {\n change_multiple_column_values(board_id: $boardId, item_id: $itemId, column_values: $columnValues, options: $options) {\n id\n }\n }\n": typeof types.ChangeItemColumnValuesDocument, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth confirming that
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This comment is here just to make sure you did the edit through the command and not manually |
||
| "\n mutation moveItemToGroup($itemId: ID!, $groupId: String!) {\n move_item_to_group(item_id: $itemId, group_id: $groupId) {\n id\n }\n }\n": typeof types.MoveItemToGroupDocument, | ||
| "\n mutation createBoard($boardKind: BoardKind!, $boardName: String!, $boardDescription: String, $workspaceId: ID) {\n create_board(\n board_kind: $boardKind\n board_name: $boardName\n description: $boardDescription\n workspace_id: $workspaceId\n empty: true\n ) {\n id\n }\n }\n": typeof types.CreateBoardDocument, | ||
| "\n mutation createColumn(\n $boardId: ID!\n $columnType: ColumnType!\n $columnTitle: String!\n $columnDescription: String\n $columnSettings: JSON\n ) {\n create_column(\n board_id: $boardId\n column_type: $columnType\n title: $columnTitle\n description: $columnDescription\n defaults: $columnSettings\n ) {\n id\n }\n }\n": typeof types.CreateColumnDocument, | ||
|
|
@@ -200,7 +200,7 @@ const documents: Documents = { | |
| "\n mutation DeleteItem($id: ID!) {\n delete_item(item_id: $id) {\n id\n }\n }\n": types.DeleteItemDocument, | ||
| "\n mutation createItem($boardId: ID!, $itemName: String!, $groupId: String, $columnValues: JSON) {\n create_item(board_id: $boardId, item_name: $itemName, group_id: $groupId, column_values: $columnValues) {\n id\n name\n }\n }\n": types.CreateItemDocument, | ||
| "\n query getBoardSchema($boardId: ID!) {\n boards(ids: [$boardId]) {\n groups {\n id\n title\n }\n columns {\n id\n type\n title\n }\n }\n }\n": types.GetBoardSchemaDocument, | ||
| "\n mutation changeItemColumnValues($boardId: ID!, $itemId: ID!, $columnValues: JSON!) {\n change_multiple_column_values(board_id: $boardId, item_id: $itemId, column_values: $columnValues) {\n id\n }\n }\n": types.ChangeItemColumnValuesDocument, | ||
| "\n mutation changeItemColumnValues($boardId: ID!, $itemId: ID!, $columnValues: JSON!, $options: JSON) {\n change_multiple_column_values(board_id: $boardId, item_id: $itemId, column_values: $columnValues, options: $options) {\n id\n }\n }\n": types.ChangeItemColumnValuesDocument, | ||
| "\n mutation moveItemToGroup($itemId: ID!, $groupId: String!) {\n move_item_to_group(item_id: $itemId, group_id: $groupId) {\n id\n }\n }\n": types.MoveItemToGroupDocument, | ||
| "\n mutation createBoard($boardKind: BoardKind!, $boardName: String!, $boardDescription: String, $workspaceId: ID) {\n create_board(\n board_kind: $boardKind\n board_name: $boardName\n description: $boardDescription\n workspace_id: $workspaceId\n empty: true\n ) {\n id\n }\n }\n": types.CreateBoardDocument, | ||
| "\n mutation createColumn(\n $boardId: ID!\n $columnType: ColumnType!\n $columnTitle: String!\n $columnDescription: String\n $columnSettings: JSON\n ) {\n create_column(\n board_id: $boardId\n column_type: $columnType\n title: $columnTitle\n description: $columnDescription\n defaults: $columnSettings\n ) {\n id\n }\n }\n": types.CreateColumnDocument, | ||
|
|
@@ -573,7 +573,7 @@ export function graphql(source: "\n query getBoardSchema($boardId: ID!) {\n | |
| /** | ||
| * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. | ||
| */ | ||
| export function graphql(source: "\n mutation changeItemColumnValues($boardId: ID!, $itemId: ID!, $columnValues: JSON!) {\n change_multiple_column_values(board_id: $boardId, item_id: $itemId, column_values: $columnValues) {\n id\n }\n }\n"): (typeof documents)["\n mutation changeItemColumnValues($boardId: ID!, $itemId: ID!, $columnValues: JSON!) {\n change_multiple_column_values(board_id: $boardId, item_id: $itemId, column_values: $columnValues) {\n id\n }\n }\n"]; | ||
| export function graphql(source: "\n mutation changeItemColumnValues($boardId: ID!, $itemId: ID!, $columnValues: JSON!, $options: JSON) {\n change_multiple_column_values(board_id: $boardId, item_id: $itemId, column_values: $columnValues, options: $options) {\n id\n }\n }\n"): (typeof documents)["\n mutation changeItemColumnValues($boardId: ID!, $itemId: ID!, $columnValues: JSON!, $options: JSON) {\n change_multiple_column_values(board_id: $boardId, item_id: $itemId, column_values: $columnValues, options: $options) {\n id\n }\n }\n"]; | ||
| /** | ||
| * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. | ||
| */ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
optionsaddition looks good. One thing — per the mcp-tool guide:getDescription()above still returns'Change the column values of an item in a monday.com board'with no mention that changes are now undoable. Consider updating it, e.g.:This way agents could inform users that the action is reversible.