-
Notifications
You must be signed in to change notification settings - Fork 73
feat(agent-toolkit): agents subgraph tools expansion #343
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
Open
NadavAvraham
wants to merge
32
commits into
master
Choose a base branch
from
feat/agent-tools-expansion
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 26 commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
b53b718
docs: add agent tools expansion design spec
NadavAvraham e4be478
docs: add agent tools expansion implementation plan
NadavAvraham a75204b
refactor(agent-toolkit): export agentFieldsFragment for reuse
NadavAvraham ec0d01b
feat(agent-toolkit): add GraphQL operations for 6 new agent tools
NadavAvraham 6cf4680
chore(agent-toolkit): regenerate dev graphql types for new agent oper…
NadavAvraham b924a9b
feat(agent-toolkit): add get_agent_catalog tool
NadavAvraham da245b0
fix(agent-toolkit): clean up get_agent_catalog variable assignment an…
NadavAvraham ca5cd0d
feat(agent-toolkit): add manage_agent_triggers tool
NadavAvraham 9897389
test(agent-toolkit): add error propagation tests for add and remove t…
NadavAvraham 45b5132
feat(agent-toolkit): add manage_agent_skills tool
NadavAvraham caec9a8
fix(agent-toolkit): improve manage_agent_skills control flow and add …
NadavAvraham 8de165d
feat(agent-toolkit): add update_agent tool
NadavAvraham 5deefcb
fix(agent-toolkit): improve update_agent null safety and test coverage
NadavAvraham 836573b
feat(agent-toolkit): add manage_agent_state tool
NadavAvraham 79a00f3
fix(agent-toolkit): improve manage_agent_state control flow, null saf…
NadavAvraham 4d64cfc
feat(agent-toolkit): add manage_agent_knowledge tool
NadavAvraham 30363fc
fix(agent-toolkit): fix update validation message and improve manage_…
NadavAvraham d23006e
fix(agent-toolkit): remove semicolons from tool descriptions to pass …
NadavAvraham 551af0e
chore(agent-toolkit): bump version to 5.11.0
NadavAvraham 4fd9a27
refactor(agent-toolkit): move returns inside try blocks and add skill…
NadavAvraham b798bbb
feat(agent-toolkit): add create_agent_skill tool
NadavAvraham ad43617
chore(agent-toolkit): bump version to 5.11.1
NadavAvraham 57346f2
chore(agent-toolkit): revert version to 5.11.0
NadavAvraham d0dabc9
refactor(agent-toolkit): fold create_agent_skill into manage_agent_sk…
NadavAvraham 560ea82
chore: remove design docs from branch (keep locally)
NadavAvraham 5470cc8
fix(agent-toolkit): address PR review feedback on agent tools
NadavAvraham 01b4755
fix(agent-toolkit): address PR #343 review feedback on agent tools
NadavAvraham 68dffd0
refactor(agent-toolkit): split create_agent_skill out of manage_agent…
NadavAvraham 5dd8870
chage tools split
NadavAvraham 9622cdf
fix(agent-toolkit): address PR review feedback on agent tools
NadavAvraham 0844441
review fixes
NadavAvraham fbb0485
chore(agent-toolkit): merge master into feat/agent-tools-expansion
NadavAvraham File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
108 changes: 108 additions & 0 deletions
108
...re/tools/platform-api-tools/agents-tools/get-agent-catalog/get-agent-catalog-tool.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,108 @@ | ||
| import { MondayAgentToolkit } from 'src/mcp/toolkit'; | ||
| import { callToolByNameRawAsync, createMockApiClient, parseToolResult } from '../../test-utils/mock-api-client'; | ||
| import { GetAgentTriggersCatalogQuery, GetAgentSkillsCatalogQuery } from 'src/monday-graphql/generated/graphql.dev/graphql'; | ||
|
|
||
| describe('GetAgentCatalogTool', () => { | ||
| let mocks: ReturnType<typeof createMockApiClient>; | ||
|
|
||
| beforeEach(() => { | ||
| mocks = createMockApiClient(); | ||
| jest.spyOn(MondayAgentToolkit.prototype as any, 'createApiClient').mockReturnValue(mocks.mockApiClient); | ||
| }); | ||
|
|
||
| const mockTrigger = { | ||
| block_reference_id: 'status-change-ref', | ||
| name: 'Status Change', | ||
| description: 'Fires when a status column changes', | ||
| field_schemas: [{ field_key: 'board_id', value_schema: 'The ID of the board to watch' }], | ||
| required_fields: [{ field_key: 'board_id', depends_on: [], optional: false }], | ||
| }; | ||
|
|
||
| const mockSkill = { | ||
| id: 'skill-1', | ||
| name: 'Board Manager', | ||
| description: 'Manages boards and items', | ||
| }; | ||
|
|
||
| it('should return triggers catalog when type is triggers', async () => { | ||
| mocks.setResponseOnce({ agent_triggers_catalog: [mockTrigger] } as GetAgentTriggersCatalogQuery); | ||
|
|
||
| const result = await callToolByNameRawAsync('get_agent_catalog', { type: 'triggers' }); | ||
| const parsed = parseToolResult(result); | ||
|
|
||
| expect(parsed.count).toBe(1); | ||
| expect(parsed.triggers[0].block_reference_id).toBe('status-change-ref'); | ||
| }); | ||
|
|
||
| it('should pass versionOverride dev when fetching triggers', async () => { | ||
| mocks.setResponseOnce({ agent_triggers_catalog: [] } as GetAgentTriggersCatalogQuery); | ||
|
|
||
| await callToolByNameRawAsync('get_agent_catalog', { type: 'triggers' }); | ||
|
|
||
| expect(mocks.getMockRequest()).toHaveBeenCalledWith( | ||
| expect.stringContaining('getAgentTriggersCatalog'), | ||
| expect.objectContaining({ block_reference_ids: undefined }), | ||
| expect.objectContaining({ versionOverride: 'dev' }), | ||
| ); | ||
| }); | ||
|
|
||
| it('should pass block_reference_ids when provided', async () => { | ||
| mocks.setResponseOnce({ agent_triggers_catalog: [mockTrigger] } as GetAgentTriggersCatalogQuery); | ||
|
|
||
| await callToolByNameRawAsync('get_agent_catalog', { type: 'triggers', block_reference_ids: ['status-change-ref'] }); | ||
|
|
||
| expect(mocks.getMockRequest()).toHaveBeenCalledWith( | ||
| expect.anything(), | ||
| expect.objectContaining({ block_reference_ids: ['status-change-ref'] }), | ||
| expect.anything(), | ||
| ); | ||
| }); | ||
|
|
||
| it('should return skills catalog when type is skills', async () => { | ||
| mocks.setResponseOnce({ agent_skills_catalog: [mockSkill] } as GetAgentSkillsCatalogQuery); | ||
|
|
||
| const result = await callToolByNameRawAsync('get_agent_catalog', { type: 'skills' }); | ||
| const parsed = parseToolResult(result); | ||
|
|
||
| expect(parsed.count).toBe(1); | ||
| expect(parsed.skills[0].id).toBe('skill-1'); | ||
| }); | ||
|
|
||
| it('should pass versionOverride dev when fetching skills', async () => { | ||
| mocks.setResponseOnce({ agent_skills_catalog: [] } as GetAgentSkillsCatalogQuery); | ||
|
|
||
| await callToolByNameRawAsync('get_agent_catalog', { type: 'skills' }); | ||
|
|
||
| expect(mocks.getMockRequest()).toHaveBeenCalledWith( | ||
| expect.stringContaining('getAgentSkillsCatalog'), | ||
| expect.anything(), | ||
| expect.objectContaining({ versionOverride: 'dev' }), | ||
| ); | ||
| }); | ||
|
|
||
| it('should return empty list with count 0 when no triggers exist', async () => { | ||
| mocks.setResponseOnce({ agent_triggers_catalog: [] } as GetAgentTriggersCatalogQuery); | ||
|
|
||
| const result = await callToolByNameRawAsync('get_agent_catalog', { type: 'triggers' }); | ||
| const parsed = parseToolResult(result); | ||
|
|
||
| expect(parsed.count).toBe(0); | ||
| expect(parsed.triggers).toEqual([]); | ||
| }); | ||
|
|
||
| it('should propagate errors when fetching triggers catalog', async () => { | ||
| mocks.setError('Unauthorized'); | ||
|
|
||
| const result = await callToolByNameRawAsync('get_agent_catalog', { type: 'triggers' }); | ||
|
|
||
| expect(result.content[0].text).toContain('Failed to fetch monday platform agent triggers catalog'); | ||
| }); | ||
|
|
||
| it('should propagate errors when fetching skills catalog', async () => { | ||
| mocks.setError('Unauthorized'); | ||
|
|
||
| const result = await callToolByNameRawAsync('get_agent_catalog', { type: 'skills' }); | ||
|
|
||
| expect(result.content[0].text).toContain('Failed to fetch monday platform agent skills catalog'); | ||
| }); | ||
| }); |
100 changes: 100 additions & 0 deletions
100
...rc/core/tools/platform-api-tools/agents-tools/get-agent-catalog/get-agent-catalog-tool.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,100 @@ | ||
| import { z } from 'zod'; | ||
| import { | ||
| GetAgentTriggersCatalogQuery, | ||
| GetAgentTriggersCatalogQueryVariables, | ||
| GetAgentSkillsCatalogQuery, | ||
| } from '../../../../../monday-graphql/generated/graphql.dev/graphql'; | ||
| import { getAgentTriggersCatalogQuery, getAgentSkillsCatalogQuery } from './get-agent-catalog.graphql.dev'; | ||
| import { ToolInputType, ToolOutputType, ToolType } from '../../../../tool'; | ||
| import { BaseMondayApiTool, createMondayApiAnnotations } from '../../base-monday-api-tool'; | ||
| import { rethrowWithContext } from '../../../../../utils'; | ||
|
|
||
| export const getAgentCatalogToolSchema = { | ||
| type: z | ||
| .enum(['triggers', 'skills']) | ||
| .describe( | ||
| 'Which catalog to fetch. "triggers" returns available trigger types with block_reference_id, field_schemas, and required_fields — use before calling manage_agent_triggers with action:add. "skills" returns available skills with id — use before calling manage_agent_skills.', | ||
| ), | ||
| block_reference_ids: z | ||
|
NadavAvraham marked this conversation as resolved.
Outdated
NadavAvraham marked this conversation as resolved.
Outdated
|
||
| .array(z.string()) | ||
| .optional() | ||
| .describe( | ||
| 'Only applies when type is "triggers". Fetch specific entries by block_reference_id instead of the full catalog. Omit to return all trigger types.', | ||
| ), | ||
| }; | ||
|
|
||
| export class GetAgentCatalogTool extends BaseMondayApiTool<typeof getAgentCatalogToolSchema> { | ||
| name = 'get_agent_catalog'; | ||
| type = ToolType.READ; | ||
| annotations = createMondayApiAnnotations({ | ||
| title: 'Get monday Platform Agent Catalog', | ||
| readOnlyHint: true, | ||
| destructiveHint: false, | ||
| idempotentHint: true, | ||
| }); | ||
|
|
||
| getDescription(): string { | ||
| return `Fetch the account-wide catalog of available trigger types or skills for monday platform agents. | ||
|
|
||
| ALWAYS call this tool first before adding a trigger or skill to an agent: | ||
| - type:"triggers" — returns entries with block_reference_id (required for manage_agent_triggers action:add), name, description, field_schemas (describes the field_values shape to pass when adding — e.g. { board_id: "<ID>" }), and required_fields (fields the user must supply before you can call add). | ||
| - type:"skills" — returns entries with id (required for manage_agent_skills), name, description. | ||
|
|
||
| Never guess or invent a block_reference_id or skill id — always look them up here first. | ||
|
|
||
| USAGE EXAMPLES: | ||
| - List all trigger types: { "type": "triggers" } | ||
| - Fetch a specific trigger type: { "type": "triggers", "block_reference_ids": ["some-block-ref-id"] } | ||
| - List all skills: { "type": "skills" }`; | ||
| } | ||
|
|
||
| getInputSchema() { | ||
| return getAgentCatalogToolSchema; | ||
| } | ||
|
|
||
| protected async executeInternal( | ||
| input: ToolInputType<typeof getAgentCatalogToolSchema>, | ||
| ): Promise<ToolOutputType<never>> { | ||
| if (input.type === 'triggers') { | ||
| try { | ||
| const variables: GetAgentTriggersCatalogQueryVariables = { | ||
| block_reference_ids: input.block_reference_ids, | ||
| }; | ||
| const res = await this.mondayApi.request<GetAgentTriggersCatalogQuery>( | ||
| getAgentTriggersCatalogQuery, | ||
| variables, | ||
| { versionOverride: 'dev' }, | ||
| ); | ||
| const catalog = res.agent_triggers_catalog ?? []; | ||
| return { | ||
| content: { | ||
| message: | ||
| 'Available trigger types for monday platform agents. Use block_reference_id and inspect field_schemas/required_fields before calling manage_agent_triggers with action:add.', | ||
| count: catalog.length, | ||
| triggers: catalog, | ||
| }, | ||
| }; | ||
| } catch (error) { | ||
| rethrowWithContext(error, 'fetch monday platform agent triggers catalog'); | ||
| } | ||
| } | ||
|
|
||
| try { | ||
| const res = await this.mondayApi.request<GetAgentSkillsCatalogQuery>( | ||
| getAgentSkillsCatalogQuery, | ||
| {}, | ||
| { versionOverride: 'dev' }, | ||
| ); | ||
| const catalog = res.agent_skills_catalog ?? []; | ||
| return { | ||
| content: { | ||
| message: 'Available skills for monday platform agents. Use id when calling manage_agent_skills.', | ||
| count: catalog.length, | ||
| skills: catalog, | ||
| }, | ||
| }; | ||
| } catch (error) { | ||
| rethrowWithContext(error, 'fetch monday platform agent skills catalog'); | ||
| } | ||
| } | ||
| } | ||
30 changes: 30 additions & 0 deletions
30
.../tools/platform-api-tools/agents-tools/get-agent-catalog/get-agent-catalog.graphql.dev.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import { gql } from 'graphql-request'; | ||
|
|
||
| export const getAgentTriggersCatalogQuery = gql` | ||
| query getAgentTriggersCatalog($block_reference_ids: [ID!]) { | ||
| agent_triggers_catalog(block_reference_ids: $block_reference_ids) { | ||
| block_reference_id | ||
| name | ||
| description | ||
| field_schemas { | ||
| field_key | ||
| value_schema | ||
| } | ||
| required_fields { | ||
| field_key | ||
| depends_on | ||
| optional | ||
| } | ||
| } | ||
| } | ||
| `; | ||
|
|
||
| export const getAgentSkillsCatalogQuery = gql` | ||
| query getAgentSkillsCatalog { | ||
| agent_skills_catalog { | ||
| id | ||
| name | ||
| description | ||
| } | ||
| } | ||
| `; |
6 changes: 6 additions & 0 deletions
6
packages/agent-toolkit/src/core/tools/platform-api-tools/agents-tools/index.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,9 @@ | ||
| export * from './get-agent/get-agent-tool'; | ||
| export * from './create-agent/create-agent-tool'; | ||
| export * from './delete-agent/delete-agent-tool'; | ||
| export * from './get-agent-catalog/get-agent-catalog-tool'; | ||
| export * from './manage-agent-triggers/manage-agent-triggers-tool'; | ||
| export * from './manage-agent-skills/manage-agent-skills-tool'; | ||
| export * from './update-agent/update-agent-tool'; | ||
| export * from './manage-agent-state/manage-agent-state-tool'; | ||
| export * from './manage-agent-knowledge/manage-agent-knowledge-tool'; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.