Custom tools + clerk-agent refactor#18
Conversation
|
Caution Review failedThe pull request is closed. WalkthroughThe changes extend the agent framework to support execution of custom tools alongside composio tools by updating the Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Agent
participant Model
participant CustomTool
participant ComposioProvider
Client->>Agent: Send request
Agent->>Model: Send prompt (with tools)
Model-->>Agent: Return tool calls
Agent->>Agent: Separate custom and composio tool calls
Agent->>CustomTool: Execute custom tool calls (via customToolExecutors)
CustomTool-->>Agent: Return custom tool results
Agent->>ComposioProvider: Execute composio tool calls
ComposioProvider-->>Agent: Return composio tool results
Agent->>Agent: Merge results
Agent-->>Client: Return response
Estimated code review effort3 (~45 minutes) Possibly related PRs
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (3)
src/agents/clerk-agent/tools.ts (2)
92-92: Consider defining types for Attio API responses.Multiple uses of
anytype reduce type safety. Consider defining interfaces for Attio API responses:interface AttioCompanyRecord { data: { values: { org_id?: Array<{ value: string | null }>; // other fields as needed }; }; id?: { record_id: string; }; } interface AttioQueryResponse { data: Array<{ id?: { record_id: string }; values: { org_id?: Array<{ value: string | null }>; }; }>; }Then replace the
anytypes:-const company = await response.json() as any; +const company = await response.json() as AttioCompanyRecord; -const search = await response.json() as any; +const search = await response.json() as AttioQueryResponse;Also applies to: 138-138, 143-143, 197-197
123-172: Consider performance implications of fetching all companies.The
getCompaniesByOrgIdfunction fetches all companies and filters in memory, which could be inefficient for large datasets.Consider:
- Checking if Attio API supports server-side filtering for substring searches
- Implementing pagination if dealing with many companies
- Adding a limit parameter to control the number of results returned
- Caching results if this operation is frequent
For now, this approach works but may need optimization as the system scales.
lib/agent.ts (1)
190-266: Well-implemented tool separation and execution logic.The implementation correctly:
- Separates custom and composio tool calls
- Executes custom tools with proper error handling
- Merges results when both tool types are used
Consider adding type definitions to replace
any:interface ToolCall { id: string; name: string; input: any; type: string; } interface ToolResult { tool_call_id: string; type: string; content: string; }Then update the filter operations:
-const customToolCalls = toolCalls.filter((call: any) => customToolNames.has(call.name)); +const customToolCalls = toolCalls.filter((call: ToolCall) => customToolNames.has(call.name));
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
lib/agent.ts(5 hunks)src/agents/clerk-agent/index.ts(5 hunks)src/agents/clerk-agent/tools.ts(3 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/src/agents/**/index.ts
Instructions used from:
Sources:
📄 CodeRabbit Inference Engine
- .cursor/rules/agent.mdc
src/agents/**/*.ts
Instructions used from:
Sources:
📄 CodeRabbit Inference Engine
- .cursor/rules/sdk.mdc
🧠 Learnings (4)
📓 Common learnings
Learnt from: CR
PR: agentuity/examples#0
File: agents/deep-research-js/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:40:05.817Z
Learning: Applies to agents/deep-research-js/src/agents/**/*.ts : Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: agents/agent-riza/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:31.143Z
Learning: Applies to agents/agent-riza/src/agents/**/*.ts : Consider agent communication (e.g., `response.handoff`, `context.getAgent`) for complex workflows
Learnt from: CR
PR: agentuity/docs#0
File: agent-docs/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-01T12:36:46.237Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: agents/tavily_agent/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:40:30.298Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/agno/from_agno/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:41:16.151Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: agents/composio/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:44.988Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/crewai/basic/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:41:34.015Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/fuse-infra#0
File: .cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-08T16:51:03.227Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: agents/Startup_News_Scraper/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:11.850Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/agent-crm#0
File: .cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-18T15:32:30.780Z
Learning: Consider agent communication for complex workflows
src/agents/clerk-agent/index.ts (21)
Learnt from: CR
PR: agentuity/examples#0
File: agents/deep-research-js/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:40:05.817Z
Learning: Applies to agents/deep-research-js/src/agents/**/*.ts : Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: agents/agent-riza/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:31.143Z
Learning: Applies to agents/agent-riza/src/agents/**/*.ts : Consider agent communication (e.g., `response.handoff`, `context.getAgent`) for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/langgraph/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:14:39.393Z
Learning: In Agentuity AI Agent files (`**/src/agents/**/index.ts`), import types such as `AgentRequest`, `AgentResponse`, and `AgentContext` from the `@agentuity/sdk` package to ensure type safety and consistency.
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/mastra/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:15:12.561Z
Learning: In Agentuity AI Agent files (`**/src/agents/**/index.ts`), import types such as `AgentRequest`, `AgentResponse`, and `AgentContext` from the `@agentuity/sdk` package to ensure type safety and consistency.
Learnt from: CR
PR: agentuity/agent-crm#0
File: .cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-18T15:32:21.381Z
Learning: Applies to **/src/agents/**/index.ts : Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description
Learnt from: CR
PR: agentuity/fuse-infra#0
File: .cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-08T16:51:03.227Z
Learning: Applies to src/agents/**/*.ts : Import types from '@agentuity/sdk'
Learnt from: CR
PR: agentuity/fuse-infra#0
File: .cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-08T16:50:51.612Z
Learning: Applies to **/src/agents/**/index.ts : Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description
Learnt from: CR
PR: agentuity/agent-crm#0
File: .cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-18T15:32:30.780Z
Learning: Applies to src/agents/**/*.ts : Import types from `@agentuity/sdk`
Learnt from: CR
PR: agentuity/examples#0
File: agents/composio/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:44.988Z
Learning: Applies to agents/composio/src/agents/**/*.ts : Import types from `@agentuity/sdk`
Learnt from: CR
PR: agentuity/docs#0
File: agent-docs/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-01T12:36:46.237Z
Learning: Applies to agent-docs/src/agents/**/*.ts : Import types from `@agentuity/sdk`
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/vercel/basic/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:16:58.079Z
Learning: Import types from @agentuity/sdk to ensure consistency and leverage type definitions.
Learnt from: CR
PR: agentuity/examples#0
File: agents/Startup_News_Scraper/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:11.850Z
Learning: Applies to agents/Startup_News_Scraper/src/agents/**/*.ts : Import types from `@agentuity/sdk`
Learnt from: CR
PR: agentuity/examples#0
File: patterns/llmAsJury/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:17:19.027Z
Learning: Import types from @agentuity/sdk to ensure consistency and type safety.
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/mastra/basic/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:15:21.314Z
Learning: For best practices in Agentuity SDK projects, use TypeScript for type safety, import types from @agentuity/sdk, use structured error handling with try/catch, leverage the provided logger, use storage APIs for data persistence, and consider agent communication for complex workflows.
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/openai/from-oai-typescript/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:15:59.829Z
Learning: In Agent files for Agentuity, always export a default function, preferably named 'Agent' or contextually after the Agent, to ensure consistency and clarity.
Learnt from: CR
PR: agentuity/collider#0
File: projects/collider-node/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-24T15:42:21.297Z
Learning: Agent files for Agentuity should export a default async function, typically named `Agent` or contextually named after the Agent, which receives `AgentRequest`, `AgentResponse`, and `AgentContext` as parameters.
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/vercel/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:16:49.315Z
Learning: When writing an Agent in TypeScript for Agentuity, always use the types provided by the `@agentuity/sdk` package for AgentRequest, AgentResponse, and AgentContext to ensure type safety and compatibility.
Learnt from: CR
PR: agentuity/examples#0
File: agentuity/sdk-js/streaming/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:40:37.445Z
Learning: Applies to agentuity/sdk-js/streaming/**/src/agents/**/index.ts : Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description
Learnt from: CR
PR: agentuity/examples#0
File: agents/composio/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:39:37.133Z
Learning: Prefer using the `agentuity agent create` command to create a new Agent
Learnt from: CR
PR: agentuity/agent-crm#0
File: .cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-18T15:32:21.381Z
Learning: Prefer using the `agentuity agent create` command to create a new Agent
Learnt from: CR
PR: agentuity/examples#0
File: agentuity/sdk-js/streaming/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:40:37.445Z
Learning: Prefer using the `agentuity agent create` command to create a new Agent
src/agents/clerk-agent/tools.ts (10)
Learnt from: CR
PR: agentuity/examples#0
File: agents/deep-research-js/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:40:05.817Z
Learning: Applies to agents/deep-research-js/src/agents/**/*.ts : Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/langgraph/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:14:39.393Z
Learning: In Agentuity AI Agent files (`**/src/agents/**/index.ts`), import types such as `AgentRequest`, `AgentResponse`, and `AgentContext` from the `@agentuity/sdk` package to ensure type safety and consistency.
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/mastra/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:15:12.561Z
Learning: In Agentuity AI Agent files (`**/src/agents/**/index.ts`), import types such as `AgentRequest`, `AgentResponse`, and `AgentContext` from the `@agentuity/sdk` package to ensure type safety and consistency.
Learnt from: CR
PR: agentuity/examples#0
File: agentuity/sdk-js/streaming/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:40:37.445Z
Learning: Applies to agentuity/sdk-js/streaming/**/src/agents/**/index.ts : All code should be in Typescript format
Learnt from: CR
PR: agentuity/docs#0
File: agent-docs/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-01T12:36:46.237Z
Learning: Applies to agent-docs/src/agents/**/*.ts : Use TypeScript for better type safety and IDE support
Learnt from: CR
PR: agentuity/examples#0
File: agents/deep-research-js/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:39:55.775Z
Learning: Applies to agents/deep-research-js/**/src/agents/**/index.ts : All code should be in Typescript format
Learnt from: CR
PR: agentuity/examples#0
File: agents/composio/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:39:37.133Z
Learning: Applies to agents/composio/**/src/agents/**/index.ts : All code should be in Typescript format
Learnt from: CR
PR: agentuity/docs#0
File: agent-docs/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-01T12:36:36.319Z
Learning: Applies to agent-docs/**/src/agents/**/index.ts : All code should be in Typescript format
Learnt from: CR
PR: agentuity/examples#0
File: agentuity/sdk-js/streaming/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:40:50.861Z
Learning: Applies to agentuity/sdk-js/streaming/src/agents/**/*.ts : Use TypeScript for better type safety and IDE support
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/mastra/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:15:12.561Z
Learning: In Agentuity AI Agent files (`**/src/agents/**/index.ts`), always use the provided logger from the `AgentContext` interface (e.g., `ctx.logger.info(...)`) for logging, rather than custom or external logging solutions.
lib/agent.ts (20)
Learnt from: CR
PR: agentuity/examples#0
File: agents/composio/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:39:37.133Z
Learning: Applies to agents/composio/**/src/agents/**/index.ts : Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description
Learnt from: CR
PR: agentuity/examples#0
File: agents/deep-research-js/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:40:05.817Z
Learning: Applies to agents/deep-research-js/src/agents/**/*.ts : Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/agent-crm#0
File: .cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-18T15:32:21.381Z
Learning: Applies to **/src/agents/**/index.ts : Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description
Learnt from: CR
PR: agentuity/fuse-infra#0
File: .cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-08T16:50:51.612Z
Learning: Applies to **/src/agents/**/index.ts : Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description
Learnt from: CR
PR: agentuity/examples#0
File: agents/agent-riza/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:31.143Z
Learning: Applies to agents/agent-riza/src/agents/**/*.ts : Consider agent communication (e.g., `response.handoff`, `context.getAgent`) for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: agents/deep-research-js/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:39:55.775Z
Learning: Applies to agents/deep-research-js/**/src/agents/**/index.ts : Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description
Learnt from: CR
PR: agentuity/examples#0
File: agents/composio/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:44.988Z
Learning: Applies to agents/composio/src/agents/**/*.ts : Use TypeScript for better type safety and IDE support
Learnt from: CR
PR: agentuity/docs#0
File: agent-docs/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-01T12:36:36.319Z
Learning: Applies to agent-docs/**/src/agents/**/index.ts : Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/mastra/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:15:12.561Z
Learning: In Agentuity AI Agent files (`**/src/agents/**/index.ts`), the default export should be an async function that handles the agent logic, typically accepting parameters `(req: AgentRequest, resp: AgentResponse, ctx: AgentContext)`.
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/langgraph/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:14:39.393Z
Learning: In Agentuity AI Agent files (`**/src/agents/**/index.ts`), the default export should be an async function that handles the agent logic, typically accepting parameters `(req: AgentRequest, resp: AgentResponse, ctx: AgentContext)`.
Learnt from: CR
PR: agentuity/collider#0
File: projects/collider-node/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-24T15:42:21.297Z
Learning: Agent files for Agentuity should export a default async function, typically named `Agent` or contextually named after the Agent, which receives `AgentRequest`, `AgentResponse`, and `AgentContext` as parameters.
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/vercel/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:16:49.315Z
Learning: When writing an Agent in TypeScript for Agentuity, always use the types provided by the `@agentuity/sdk` package for AgentRequest, AgentResponse, and AgentContext to ensure type safety and compatibility.
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/openai/from-oai-typescript/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:16:08.480Z
Learning: In the Agentuity JavaScript SDK, the main handler for an agent should implement the AgentHandler type: (request: AgentRequest, response: AgentResponse, context: AgentContext) => Promise<AgentResponseType>.
Learnt from: CR
PR: agentuity/examples#0
File: patterns/llmAsJury/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:17:19.027Z
Learning: In the Agentuity JavaScript SDK, the main handler for an agent should implement the AgentHandler type: (request: AgentRequest, response: AgentResponse, context: AgentContext) => Promise<AgentResponseType>.
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/vercel/basic/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:16:58.079Z
Learning: In the Agentuity JavaScript SDK, the main handler for an agent should implement the AgentHandler type: (request: AgentRequest, response: AgentResponse, context: AgentContext) => Promise<AgentResponseType>.
Learnt from: CR
PR: agentuity/examples#0
File: agentuity/sdk-js/streaming/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:40:37.445Z
Learning: Applies to agentuity/sdk-js/streaming/**/src/agents/**/index.ts : Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description
Learnt from: CR
PR: agentuity/examples#0
File: agents/composio/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:39:37.133Z
Learning: Prefer using the `agentuity agent create` command to create a new Agent
Learnt from: CR
PR: agentuity/examples#0
File: agents/agent-riza/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:39:18.709Z
Learning: Prefer using the `agentuity agent create` command to create a new Agent
Learnt from: CR
PR: agentuity/examples#0
File: agentuity/sdk-js/streaming/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:40:37.445Z
Learning: Prefer using the `agentuity agent create` command to create a new Agent
Learnt from: CR
PR: agentuity/agent-crm#0
File: .cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-18T15:32:21.381Z
Learning: Prefer using the `agentuity agent create` command to create a new Agent
🧬 Code Graph Analysis (1)
src/agents/clerk-agent/tools.ts (2)
lib/helpers.ts (3)
addOrgToOrgIdString(41-53)parseOrgIdString(26-33)updateOrgNameInOrgIdString(56-76)lib/attio.ts (3)
addOrgToOrgIdString(6-6)parseOrgIdString(6-6)updateOrgNameInOrgIdString(6-6)
🪛 Biome (1.9.4)
src/agents/clerk-agent/tools.ts
[error] 68-68: Don't use 'Function' as a type.
Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.
(lint/complexity/noBannedTypes)
[error] 92-92: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
[error] 138-138: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
[error] 143-143: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
[error] 197-197: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
lib/agent.ts
[error] 9-9: Don't use 'Function' as a type.
Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.
(lint/complexity/noBannedTypes)
[error] 191-191: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
[error] 192-192: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
[error] 196-196: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
[error] 199-200: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
[error] 244-244: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
[error] 244-244: Unexpected any. Specify a different type.
any disables many type checking rules. Its use should be avoided.
(lint/suspicious/noExplicitAny)
🔇 Additional comments (7)
src/agents/clerk-agent/index.ts (3)
2-2: LGTM! Clear and specific naming for custom tools.The import names
clerkExtraToolsandclerkToolExecutorsclearly indicate these are custom tools specific to the clerk-agent.
14-106: Well-structured prompt with clear tool distinctions.The updated prompt effectively:
- Distinguishes between composio ATTIO toolkit and custom organization management tools
- Provides clear workflow steps for each event type
- Includes important notes about ATTIO attribute naming conventions
This will help the agent use the appropriate tools for each task.
108-108: Correct integration with the extended createAgent function.The function call properly passes the custom tools and executors to enable the clerk-agent to use both composio and custom tools.
src/agents/clerk-agent/tools.ts (2)
1-1: LGTM! Appropriate helper imports.The imported helper functions provide the necessary utilities for manipulating the pipe-delimited organization ID strings.
3-64: Well-defined custom tools with clear schemas.The tool definitions:
- Follow the Anthropic format correctly
- Have descriptive names and clear descriptions
- Define comprehensive input schemas with required fields
- Document the pipe-delimited format for organization IDs
lib/agent.ts (2)
47-48: Efficient approach for custom tool identification.Using a Set for O(1) lookup performance when distinguishing between custom and composio tools.
269-269: Good addition for tracking tool call history.Accumulating all tool calls across iterations provides valuable context for the agent's decision-making process.
| addOrgToCompany: async ({ | ||
| // Tool executors for the custom tools | ||
| // These will be called by composio when the tools are invoked | ||
| export const clerkToolExecutors: Record<string, Function> = { |
There was a problem hiding this comment.
Replace Function type with explicit type definitions.
Using Function as a type is too permissive and loses type safety benefits.
Define explicit types for the tool executors:
-export const clerkToolExecutors: Record<string, Function> = {
+type ToolExecutor<T = any> = (args: T) => Promise<any>;
+
+export const clerkToolExecutors: Record<string, ToolExecutor> = {Or even better, create specific types for each tool's arguments:
type AddOrgToCompanyArgs = {
companyId: string;
orgName: string;
orgId: string;
};
type GetCompaniesByOrgIdArgs = {
orgId: string;
};
type UpdateOrgNameInCompanyArgs = {
companyId: string;
orgId: string;
newOrgName: string;
};
type ClerkToolExecutors = {
addOrgToCompany: ToolExecutor<AddOrgToCompanyArgs>;
getCompaniesByOrgId: ToolExecutor<GetCompaniesByOrgIdArgs>;
updateOrgNameInCompany: ToolExecutor<UpdateOrgNameInCompanyArgs>;
};
export const clerkToolExecutors: ClerkToolExecutors = {
// ... executors
};🧰 Tools
🪛 Biome (1.9.4)
[error] 68-68: Don't use 'Function' as a type.
Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.
(lint/complexity/noBannedTypes)
🤖 Prompt for AI Agents
In src/agents/clerk-agent/tools.ts at line 68, replace the use of the generic
Function type for clerkToolExecutors with explicit, well-defined types for each
tool executor's arguments. Define specific argument types for each executor
function, create a ClerkToolExecutors type mapping executor names to their
corresponding ToolExecutor types with these argument types, and then update the
clerkToolExecutors object to use this new ClerkToolExecutors type for improved
type safety and clarity.
| export const createAgent = ( | ||
| prompt: string, | ||
| extraTools: any[] = [], | ||
| customToolExecutors: Record<string, Function> = {}, |
There was a problem hiding this comment.
Replace Function type with a specific executor type.
The Function type is too permissive and should be replaced with a proper type definition.
+type ToolExecutor = (args: any) => Promise<any>;
+
export const createAgent = (
prompt: string,
extraTools: any[] = [],
- customToolExecutors: Record<string, Function> = {},
+ customToolExecutors: Record<string, ToolExecutor> = {},🧰 Tools
🪛 Biome (1.9.4)
[error] 9-9: Don't use 'Function' as a type.
Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.
(lint/complexity/noBannedTypes)
🤖 Prompt for AI Agents
In lib/agent.ts at line 9, replace the overly broad `Function` type used in the
`customToolExecutors` record with a more specific executor function type that
accurately describes the expected function signature. Define or import the
appropriate type for the executor functions and use it instead of `Function` to
improve type safety and clarity.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/agents/clerk-agent/index.ts (2)
1-1: Consider importing types from @agentuity/sdk for better type safety.While the current import is clean, consider importing relevant types from
@agentuity/sdkto follow coding guidelines and improve type safety, especially if you plan to add more functionality.+import type { AgentRequest, AgentResponse, AgentContext } from '@agentuity/sdk'; import { createAgent } from "../../../lib/agent";
91-91: Consider explicitly naming the default export function.According to coding guidelines, prefer naming the default function "Agent" or contextually based on the agent description. Consider making this more explicit:
-export default createAgent(clerkWebhookPrompt); +const ClerkAgent = createAgent(clerkWebhookPrompt); +export default ClerkAgent;This improves readability and follows the coding guideline for explicit function naming.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/agents/clerk-agent/index.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/src/agents/**/index.ts
Instructions used from:
Sources:
📄 CodeRabbit Inference Engine
- .cursor/rules/agent.mdc
src/agents/**/*.ts
Instructions used from:
Sources:
📄 CodeRabbit Inference Engine
- .cursor/rules/sdk.mdc
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
PR: agentuity/examples#0
File: agents/deep-research-js/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:40:05.817Z
Learning: Applies to agents/deep-research-js/src/agents/**/*.ts : Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: agents/agent-riza/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:31.143Z
Learning: Applies to agents/agent-riza/src/agents/**/*.ts : Consider agent communication (e.g., `response.handoff`, `context.getAgent`) for complex workflows
Learnt from: CR
PR: agentuity/docs#0
File: agent-docs/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-01T12:36:46.237Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: agents/tavily_agent/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:40:30.298Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: agents/composio/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:44.988Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/agno/from_agno/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:41:16.151Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/crewai/basic/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:41:34.015Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/fuse-infra#0
File: .cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-08T16:51:03.227Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/agent-crm#0
File: .cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-18T15:32:30.780Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: agents/Startup_News_Scraper/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:11.850Z
Learning: Consider agent communication for complex workflows
src/agents/clerk-agent/index.ts (16)
Learnt from: CR
PR: agentuity/examples#0
File: agents/deep-research-js/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:40:05.817Z
Learning: Applies to agents/deep-research-js/src/agents/**/*.ts : Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: agents/agent-riza/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:31.143Z
Learning: Applies to agents/agent-riza/src/agents/**/*.ts : Consider agent communication (e.g., `response.handoff`, `context.getAgent`) for complex workflows
Learnt from: CR
PR: agentuity/agent-crm#0
File: .cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-18T15:32:21.381Z
Learning: Applies to **/src/agents/**/index.ts : Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description
Learnt from: CR
PR: agentuity/fuse-infra#0
File: .cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-08T16:50:51.612Z
Learning: Applies to **/src/agents/**/index.ts : Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description
Learnt from: CR
PR: agentuity/examples#0
File: agents/Startup_News_Scraper/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:38:58.657Z
Learning: Applies to agents/Startup_News_Scraper/**/src/agents/**/index.ts : Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description
Learnt from: CR
PR: agentuity/docs#0
File: agent-docs/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-01T12:36:36.319Z
Learning: Applies to agent-docs/**/src/agents/**/index.ts : Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/mastra/basic/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:15:21.314Z
Learning: For best practices in Agentuity SDK projects, use TypeScript for type safety, import types from @agentuity/sdk, use structured error handling with try/catch, leverage the provided logger, use storage APIs for data persistence, and consider agent communication for complex workflows.
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/mastra/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:15:12.561Z
Learning: In Agentuity AI Agent files (`**/src/agents/**/index.ts`), always use the provided logger from the `AgentContext` interface (e.g., `ctx.logger.info(...)`) for logging, rather than custom or external logging solutions.
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/langgraph/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:14:39.393Z
Learning: In Agentuity AI Agent files (`**/src/agents/**/index.ts`), always use the provided logger from the `AgentContext` interface (e.g., `ctx.logger.info(...)`) for logging, rather than custom or external logging solutions.
Learnt from: CR
PR: agentuity/examples#0
File: agentuity/sdk-js/streaming/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:40:37.445Z
Learning: Applies to agentuity/sdk-js/streaming/**/src/agents/**/index.ts : Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/vercel/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:16:49.315Z
Learning: When writing an Agent in TypeScript for Agentuity, always use the types provided by the `@agentuity/sdk` package for AgentRequest, AgentResponse, and AgentContext to ensure type safety and compatibility.
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/openai/from-oai-typescript/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:15:59.829Z
Learning: In Agent files for Agentuity, always export a default function, preferably named 'Agent' or contextually after the Agent, to ensure consistency and clarity.
Learnt from: CR
PR: agentuity/examples#0
File: agents/Startup_News_Scraper/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:38:58.657Z
Learning: Applies to agents/Startup_News_Scraper/**/src/agents/**/index.ts : The file should export a default function
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/vercel/basic/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:16:58.079Z
Learning: Import types from @agentuity/sdk to ensure consistency and leverage type definitions.
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/openai/from-oai-typescript/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:16:08.480Z
Learning: Types should be imported from @agentuity/sdk for consistency and type safety.
Learnt from: CR
PR: agentuity/collider#0
File: projects/collider-node/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-24T15:42:21.297Z
Learning: Agent files for Agentuity should export a default async function, typically named `Agent` or contextually named after the Agent, which receives `AgentRequest`, `AgentResponse`, and `AgentContext` as parameters.
🔇 Additional comments (1)
src/agents/clerk-agent/index.ts (1)
1-92: Overall structure follows guidelines well.The file structure is clean and follows most coding guidelines:
- ✅ Exports a default function
- ✅ Uses TypeScript format
- ✅ Focused and maintainable structure
The refactor successfully simplifies the agent definition by moving complexity to the
createAgentfunction and custom tools, which aligns with the PR objectives.
| const clerkWebhookPrompt = ` | ||
| You are processing webhooks from Clerk. | ||
| Your job is to manage people and companies in Attio based on Clerk user and organization events. | ||
|
|
||
| ## Webhook Structure | ||
| All webhooks contain a \`type\` field that determines the action. | ||
| Extract the primary email from \`data.email_addresses[0].email_address\`. | ||
| Convert timestamps from Unix milliseconds to ISO strings if needed. | ||
|
|
||
| ## Available Tools: | ||
| - \`getPersonByEmail\` - Find person by email | ||
| - \`getPersonByClerkID\` - Find person by Clerk user ID | ||
| - \`assertPerson\` - Create/update person (upsert) | ||
| - \`getCompanyByPersonEmail\` - Find company associated with person | ||
| - \`getCompanyByRecordID\` - Get company by Attio record ID | ||
| - \`updateCompany\` - Update company fields | ||
| - \`addOrgToCompany\` - Add organization to company's orgId field (handles string concatenation) | ||
| - \`getCompaniesByOrgId\` - Find all companies that contain a specific organization ID in their orgId field | ||
| - \`updateOrgNameInCompany\` - Update an organization's name in a company's orgId field based on org ID | ||
|
|
||
| ## Organization ID Format | ||
| Companies store multiple organizations in a single \`orgId\` string field using this format: | ||
| - Single org: \`"Organization Name:org_id"\` | ||
| - Multiple orgs: \`"Org1:id1|Org2:id2|Org3:id3"\` | ||
| - Use pipe \`|\` as delimiter between organizations | ||
| - Use colon \`:\` to separate name from ID | ||
|
|
||
| ## Workflow by Event Type: | ||
| ## ABSOLUTE RULES - NEVER VIOLATE THESE: | ||
| 1. MAXIMUM 6 iterations total - STOP at 6, no exceptions | ||
| 2. NEVER make the same tool call twice with identical parameters | ||
| 3. If a search fails, try ONE alternative pattern, then GIVE UP on that search | ||
| 4. For organization.created: ONLY update existing companies, NEVER create new ones | ||
| 5. Track what you've tried - do NOT repeat failed searches | ||
|
|
||
| ## Available ATTIO Tools: | ||
| - \`ATTIO_FIND_RECORD\` - Find records | ||
| - \`ATTIO_CREATE_RECORD\` - Create new records | ||
| - \`ATTIO_UPDATE_RECORD\` - Update existing records | ||
| - \`ATTIO_LIST_RECORDS\` - List records (emergency only) | ||
| - \`ATTIO_GET_OBJECT\` - Get schema (emergency only) | ||
|
|
||
| ## SIMPLE Workflow by Event Type: | ||
|
|
||
| ### user.created | ||
| **Data**: \`data.id\` (Clerk user ID), \`data.created_at\` (Unix timestamp), \`data.email_addresses\`, \`data.first_name\`, \`data.last_name\` | ||
|
|
||
| **Steps**: | ||
| 1. Extract email from \`data.email_addresses[0].email_address\` | ||
| 2. Convert \`data.created_at\` from Unix milliseconds to ISO string | ||
| 3. **Check if person already exists**: Use \`getPersonByEmail\` to see if they're already in Attio (e.g., from SmartLead) | ||
| 4. **Always use \`assertPerson\`** to create/update the person with: | ||
| - \`email\`: extracted email | ||
| - \`firstName\`: \`data.first_name\` | ||
| - \`lastName\`: \`data.last_name\` | ||
| - \`userId\`: \`data.id\` (this will add/update the Clerk user ID for existing users) | ||
| - \`accountCreationDate\`: converted timestamp | ||
| 5. **Log the action**: Clearly log whether this was updating an existing person or creating a new one | ||
| 6. If person has company domain, use \`getCompanyByPersonEmail\` to link them | ||
|
|
||
| ### user.updated | ||
| **Data**: \`data.id\`, \`data.email_addresses\`, \`data.organization_memberships\` | ||
|
|
||
| **Steps**: | ||
| 1. Use \`getPersonByClerkID\` to find existing person | ||
| 2. If found, extract new email and team info | ||
| 3. Use \`assertPerson\` to update with new information | ||
| 4. If team changed, update associated company | ||
| **Target: Complete in 3 iterations** | ||
| 1. **Search person**: \`ATTIO_FIND_RECORD\` with email | ||
| 2. **Create/update person**: Based on search result | ||
| 3. **Search/create company**: Based on email domain | ||
|
|
||
| ### user.updated | ||
| **Target: Complete in 2 iterations** | ||
| 1. **Search person**: \`ATTIO_FIND_RECORD\` by user_id, if fails try email | ||
| 2. **Update person**: \`ATTIO_UPDATE_RECORD\` | ||
|
|
||
| ### organization.created | ||
| **Data**: \`data.id\` (org ID), \`data.name\` (org name), \`data.created_by\` (user ID who created it) | ||
| **Target: Complete in 4 iterations MAXIMUM** | ||
|
|
||
| **CRITICAL: This is an ORG CREATED event - the PERSON and COMPANY already exist from user.created. Your job is to FIND them and ADD the org to the company.** | ||
|
|
||
| **LINEAR WORKFLOW - Do NOT deviate:** | ||
|
|
||
| **Step 1: Find the creator person** | ||
| - Try: \`ATTIO_FIND_RECORD\` with \`object_id: "people"\`, \`attributes: { user_id: [{ value: "data.created_by" }] }\` | ||
| - If fails: Try \`ATTIO_LIST_RECORDS\` for people (limit 100), manually find person with matching user_id | ||
| - If still fails: ABORT - log error and stop | ||
|
|
||
| **Step 2: Extract company domain** | ||
| - Get creator's email from person record: \`person.values.email_addresses[0].email_address\` | ||
| - Extract domain: \`email.split('@')[1]\` | ||
|
|
||
| **Step 3: Find the existing company** | ||
| - Try: \`ATTIO_FIND_RECORD\` with \`object_id: "companies"\`, \`attributes: { domains: [{ value: "extracted_domain" }] }\` | ||
| - If fails: Try \`ATTIO_LIST_RECORDS\` for companies (limit 100), manually find company with matching domain | ||
| - If still fails: ABORT - log error, do NOT create company | ||
|
|
||
| **Step 4: Update company with org** | ||
| - Get current \`org_id\` value from company record | ||
| - Parse existing string: \`split('|')\` then \`split(':')\` for each part | ||
| - Check if \`data.id\` already exists in parsed orgs | ||
| - If not duplicate: append \`"|data.name:data.id"\` to existing string | ||
| - Update company: \`ATTIO_UPDATE_RECORD\` with new org_id value | ||
|
|
||
| **Steps**: | ||
| 1. Use \`getPersonByClerkID\` with \`data.created_by\` to find the user who created the organization | ||
| 2. Use \`getCompanyByPersonEmail\` to find their existing company (Attio auto-creates companies based on email domain) | ||
| 3. Use \`addOrgToCompany\` with: | ||
| - \`companyId\`: company record ID | ||
| - \`orgName\`: \`data.name\` | ||
| - \`orgId\`: \`data.id\` | ||
| 4. This will automatically append the new org to the existing orgId string | ||
| **CRITICAL RULES:** | ||
| - Do NOT repeat failed searches | ||
| - Do NOT create new companies | ||
| - Do NOT make more than 4 tool calls | ||
| - If you can't find creator or company, ABORT with error message | ||
|
|
||
| ### organization.updated | ||
| **Data**: \`data.id\` (org ID), \`data.name\` (org name), \`data.public_metadata.hasOnboarded\` | ||
|
|
||
| **Steps**: | ||
| 1. Use \`getCompaniesByOrgId\` with \`data.id\` to find all companies that have this organization ID in their orgId string | ||
| 2. For each company found: | ||
| - Check if the org name in the orgId string matches \`data.name\` | ||
| - If the name is different, use \`updateOrgNameInCompany\` to update the org name in the orgId string | ||
| - If \`data.public_metadata.hasOnboarded\` is \`true\`, use \`updateCompany\` to update the \`hasOnboarded\` field to \`true\` | ||
| 3. Log all actions taken for debugging | ||
|
|
||
| ## Error Handling: | ||
| - If person not found when expected, log warning and continue | ||
| - If company operations fail, ensure person operations still complete | ||
| - Always log the action taken for debugging | ||
| - The \`addOrgToCompany\` tool automatically handles duplicate prevention | ||
|
|
||
| ## Data Format: | ||
| - Store organization IDs as: \`"Organization Name:org_id|Another Org:org_id2"\` | ||
| - Convert Unix timestamps (milliseconds) to ISO strings: \`new Date(timestamp).toISOString()\` | ||
| - Use ISO timestamps for dates | ||
| - Validate email addresses before processing | ||
|
|
||
| ## General Flow: | ||
| 1. Always start by identifying the event type from the \`type\` field | ||
| 2. Extract and validate required data fields | ||
| 3. Convert Unix timestamps to ISO strings when needed | ||
| 4. Check if entities exist before creating/updating | ||
| 5. Use appropriate tools for orgId string manipulation | ||
| 6. Log all actions taken | ||
| 7. Handle errors gracefully without stopping the workflow | ||
| **Target: Complete in 3 iterations** | ||
| 1. **Find companies**: \`ATTIO_LIST_RECORDS\` for companies | ||
| 2. **Filter and parse**: Find companies with matching org_id in string | ||
| 3. **Update companies**: Modify org data and update records | ||
|
|
||
| ## Efficiency Rules: | ||
| - Count your iterations - stop at limit | ||
| - Never repeat identical tool calls | ||
| - Use simple string operations for org_id manipulation | ||
| - If searches fail after one alternative, give up and log error | ||
| - Prioritize completing workflow over perfect data | ||
|
|
||
| ## Data Extraction: | ||
| - Creator ID: \`data.created_by\` | ||
| - Org ID: \`data.id\` | ||
| - Org Name: \`data.name\` | ||
| - Email domain: \`email.split('@')[1]\` | ||
| - Parse org string: \`orgString.split('|').map(part => { const [name, id] = part.split(':'); return {name, id}; })\` | ||
|
|
||
| **Remember: For organization.created, the person and company ALREADY EXIST. Find them and update the company's org_id field. Do NOT create anything new.** | ||
| `; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Address potential data structure assumptions and error handling.
The prompt contains several hardcoded assumptions about data structures that could cause runtime errors:
- Line 47:
person.values.email_addresses[0].email_addressassumes the first email address always exists - Line 48:
email.split('@')[1]assumes valid email format - Line 57-58: String parsing assumes specific org_id format
Consider adding null checks and validation in the prompt instructions or handling these edge cases gracefully.
-**Step 2: Extract company domain**
-- Get creator's email from person record: \`person.values.email_addresses[0].email_address\`
-- Extract domain: \`email.split('@')[1]\`
+**Step 2: Extract company domain**
+- Get creator's email from person record: \`person.values.email_addresses?.[0]?.email_address\`
+- Validate email exists and has valid format before extracting domain
+- Extract domain: \`email.split('@')[1]\` (only if email contains '@')Additionally, consider centralizing error handling rules rather than scattering them throughout the workflow sections.
🤖 Prompt for AI Agents
In src/agents/clerk-agent/index.ts around lines 40 to 60, the prompt assumes
person.values.email_addresses[0].email_address always exists and that the email
format is valid for splitting, and also assumes a specific format for parsing
org_id strings. To fix this, update the prompt instructions to include checks
for the existence of email_addresses and validate the email format before
splitting. Similarly, clarify the expected org_id string format and add guidance
to handle unexpected formats gracefully. Additionally, consolidate error
handling instructions into a single section to avoid repetition and improve
clarity.
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
src/agents/clerk-agent/tools.ts (1)
68-68: Function type issue persists in commented code.The previous review comment about replacing the generic
Functiontype with explicit type definitions is still applicable to this commented code. When this code is re-enabled, the type safety issue will resurface.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/agents/clerk-agent/tools.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/agents/**/*.ts
Instructions used from:
Sources:
📄 CodeRabbit Inference Engine
- .cursor/rules/sdk.mdc
🧠 Learnings (2)
📓 Common learnings
Learnt from: CR
PR: agentuity/examples#0
File: agents/deep-research-js/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:40:05.817Z
Learning: Applies to agents/deep-research-js/src/agents/**/*.ts : Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: agents/agent-riza/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:31.143Z
Learning: Applies to agents/agent-riza/src/agents/**/*.ts : Consider agent communication (e.g., `response.handoff`, `context.getAgent`) for complex workflows
Learnt from: CR
PR: agentuity/docs#0
File: agent-docs/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-01T12:36:46.237Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: agents/tavily_agent/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:40:30.298Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: agents/composio/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:44.988Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/agno/from_agno/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:41:16.151Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/crewai/basic/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:41:34.015Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/fuse-infra#0
File: .cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-08T16:51:03.227Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/agent-crm#0
File: .cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-18T15:32:30.780Z
Learning: Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: agents/Startup_News_Scraper/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:11.850Z
Learning: Consider agent communication for complex workflows
src/agents/clerk-agent/tools.ts (23)
Learnt from: CR
PR: agentuity/examples#0
File: agents/deep-research-js/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:40:05.817Z
Learning: Applies to agents/deep-research-js/src/agents/**/*.ts : Consider agent communication for complex workflows
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/langgraph/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:14:39.393Z
Learning: In Agentuity AI Agent files (`**/src/agents/**/index.ts`), import types such as `AgentRequest`, `AgentResponse`, and `AgentContext` from the `@agentuity/sdk` package to ensure type safety and consistency.
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/mastra/basic/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:15:12.561Z
Learning: In Agentuity AI Agent files (`**/src/agents/**/index.ts`), import types such as `AgentRequest`, `AgentResponse`, and `AgentContext` from the `@agentuity/sdk` package to ensure type safety and consistency.
Learnt from: CR
PR: agentuity/examples#0
File: agents/composio/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:39:37.133Z
Learning: Applies to agents/composio/**/src/agents/**/index.ts : All code should be in Typescript format
Learnt from: CR
PR: agentuity/examples#0
File: agents/deep-research-js/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:39:55.775Z
Learning: Applies to agents/deep-research-js/**/src/agents/**/index.ts : All code should be in Typescript format
Learnt from: CR
PR: agentuity/examples#0
File: agents/Startup_News_Scraper/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:38:58.657Z
Learning: Applies to agents/Startup_News_Scraper/**/src/agents/**/index.ts : Prefer loading types from the node modules package `@agentuity/sdk` in the node_modules folder
Learnt from: CR
PR: agentuity/examples#0
File: agents/Startup_News_Scraper/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:11.850Z
Learning: Applies to agents/Startup_News_Scraper/src/agents/**/*.ts : Import types from `@agentuity/sdk`
Learnt from: CR
PR: agentuity/examples#0
File: agentuity/sdk-js/streaming/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:40:37.445Z
Learning: Applies to agentuity/sdk-js/streaming/**/src/agents/**/index.ts : All code should be in Typescript format
Learnt from: CR
PR: agentuity/agent-crm#0
File: .cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-18T15:32:21.381Z
Learning: Applies to **/src/agents/**/index.ts : All code should be in Typescript format
Learnt from: CR
PR: agentuity/fuse-infra#0
File: .cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-08T16:50:51.612Z
Learning: Applies to **/src/agents/**/index.ts : All code should be in Typescript format
Learnt from: CR
PR: agentuity/fuse-infra#0
File: .cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-08T16:51:03.227Z
Learning: Applies to src/agents/**/*.ts : Use TypeScript for better type safety and IDE support
Learnt from: CR
PR: agentuity/agent-crm#0
File: .cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-18T15:32:30.780Z
Learning: Applies to src/agents/**/*.ts : Use TypeScript for better type safety and IDE support
Learnt from: CR
PR: agentuity/docs#0
File: agent-docs/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-01T12:36:46.237Z
Learning: Applies to agent-docs/src/agents/**/*.ts : Use TypeScript for better type safety and IDE support
Learnt from: CR
PR: agentuity/examples#0
File: agents/deep-research-js/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:40:05.817Z
Learning: Applies to agents/deep-research-js/src/agents/**/*.ts : Use TypeScript for better type safety and IDE support
Learnt from: CR
PR: agentuity/examples#0
File: agents/composio/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:44.988Z
Learning: Applies to agents/composio/src/agents/**/*.ts : Use TypeScript for better type safety and IDE support
Learnt from: CR
PR: agentuity/examples#0
File: agents/agent-riza/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-07-17T13:39:31.143Z
Learning: Applies to agents/agent-riza/src/agents/**/*.ts : Use TypeScript for better type safety and IDE support
Learnt from: CR
PR: agentuity/app#0
File: .cursor/rules/monorepo.mdc:0-0
Timestamp: 2025-07-18T15:53:39.814Z
Learning: Applies to **/*.{ts,tsx} : Implement proper type safety and inference.
Learnt from: pec1985
PR: agentuity/app#583
File: lib/data/queries/objectstore.ts:93-93
Timestamp: 2025-06-24T16:59:49.935Z
Learning: The objEnum utility function in lib/data/util.ts creates TypeScript enum-like objects where each key-value pair is identical (e.g., {agentuity: 'agentuity', google: 'google'}). When using typeof ObjectStoreProviderEnum as a parameter type, it expects this enum object type, but runtime code needs the string values, requiring type casting as unknown as string union to bridge this gap.
Learnt from: CR
PR: agentuity/agent-crm#0
File: .cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-18T15:32:21.381Z
Learning: Applies to **/src/agents/**/index.ts : Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description
Learnt from: CR
PR: agentuity/fuse-infra#0
File: .cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-08T16:50:51.612Z
Learning: Applies to **/src/agents/**/index.ts : Prefer naming the default function Agent or the name of the Agent based on the context of the Agent description
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/openai/from-oai-typescript/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-06-23T17:15:59.829Z
Learning: In Agent files for Agentuity, always export a default function, preferably named 'Agent' or contextually after the Agent, to ensure consistency and clarity.
Learnt from: CR
PR: agentuity/examples#0
File: frameworks/mastra/basic/.cursor/rules/sdk.mdc:0-0
Timestamp: 2025-06-23T17:15:21.314Z
Learning: For best practices in Agentuity SDK projects, use TypeScript for type safety, import types from @agentuity/sdk, use structured error handling with try/catch, leverage the provided logger, use storage APIs for data persistence, and consider agent communication for complex workflows.
Learnt from: CR
PR: agentuity/examples#0
File: agents/composio/.cursor/rules/agent.mdc:0-0
Timestamp: 2025-07-17T13:39:37.133Z
Learning: Applies to agents/composio/**/src/agents/**/index.ts : The file should export a default function
🔇 Additional comments (2)
src/agents/clerk-agent/tools.ts (2)
1-231: Clarify the purpose of commenting out the entire file.The entire file containing custom tools and executors is commented out, which effectively removes all custom tool functionality for the clerk-agent. This could impact the agent's ability to perform organization management operations as described in the PR objectives.
Please clarify whether this is:
- Intentional removal of custom tools in favor of composio tools only
- Temporary commenting during development/testing
- An incomplete implementation that needs to be re-enabled
5-64: Well-structured tool definitions follow best practices.The commented Anthropic format tool definitions are well-structured with:
- Clear descriptions explaining the business logic
- Proper input schemas with required fields
- Appropriate type definitions for parameters
This follows the coding guidelines for TypeScript type safety when re-enabled.
| // const response = await fetch(`https://api.attio.com/v2/objects/companies/records/${companyId}`, { | ||
| // method: "GET", | ||
| // headers: { | ||
| // Authorization: `Bearer ${process.env.ATTIO_AUTH_TOKEN}`, | ||
| // "Content-Type": "application/json", | ||
| // }, | ||
| // }); | ||
|
|
||
| // if (!response.ok) { | ||
| // throw new Error(`Failed to get company: ${response.status}`); | ||
| // } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add proper error handling and logging for API calls.
The commented executor functions make direct Attio API calls but lack comprehensive error handling and logging. Consider adding:
// Add proper error handling with detailed context
import { logger } from '@agentuity/sdk';
// Example for addOrgToCompany executor:
try {
const response = await fetch(`https://api.attio.com/v2/objects/companies/records/${companyId}`, {
method: "GET",
headers: {
Authorization: `Bearer ${process.env.ATTIO_AUTH_TOKEN}`,
"Content-Type": "application/json",
},
});
if (!response.ok) {
const errorText = await response.text();
logger.error(`Failed to get company ${companyId}: ${response.status} - ${errorText}`);
throw new Error(`Failed to get company: ${response.status} - ${errorText}`);
}
const company = await response.json();
logger.info(`Successfully retrieved company ${companyId}`);
// ... rest of the logic
} catch (error) {
logger.error(`Error in addOrgToCompany for company ${companyId}:`, error);
throw error;
}Also applies to: 101-118, 125-136, 157-169, 185-196, 210-227
🤖 Prompt for AI Agents
In src/agents/clerk-agent/tools.ts between lines 80-90 and also in the ranges
101-118, 125-136, 157-169, 185-196, and 210-227, the commented-out executor
functions making Attio API calls lack proper error handling and logging. To fix
this, wrap the fetch calls in try-catch blocks, use the logger from
'@agentuity/sdk' to log detailed error messages including response status and
error text when the response is not ok, log successful retrievals, and rethrow
errors after logging to ensure proper error propagation and easier debugging.
Summary by CodeRabbit
New Features
Refactor
Bug Fixes