feat(tools): added more intercom tools (#3022)

This commit is contained in:
Waleed
2026-01-26 21:41:44 -08:00
committed by GitHub
parent 077e702dd8
commit 46ba315701
58 changed files with 2966 additions and 115 deletions

View File

@@ -647,6 +647,42 @@ Retrieve a single ticket by ID from Intercom. Returns API-aligned fields only.
| `ticketId` | string | ID of the retrieved ticket |
| `success` | boolean | Operation success status |
### `intercom_update_ticket`
Update a ticket in Intercom (change state, assignment, attributes)
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `ticketId` | string | Yes | The ID of the ticket to update |
| `ticket_attributes` | string | No | JSON object with ticket attributes \(e.g., \{"_default_title_":"New Title","_default_description_":"Updated description"\}\) |
| `open` | boolean | No | Set to false to close the ticket, true to keep it open |
| `is_shared` | boolean | No | Whether the ticket is visible to users |
| `snoozed_until` | number | No | Unix timestamp for when the ticket should reopen |
| `admin_id` | string | No | The ID of the admin performing the update \(needed for workflows and attribution\) |
| `assignee_id` | string | No | The ID of the admin or team to assign the ticket to. Set to "0" to unassign. |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `ticket` | object | The updated ticket object |
| ↳ `id` | string | Unique identifier for the ticket |
| ↳ `type` | string | Object type \(ticket\) |
| ↳ `ticket_id` | string | Ticket ID shown in Intercom UI |
| ↳ `ticket_state` | string | State of the ticket |
| ↳ `ticket_attributes` | object | Attributes of the ticket |
| ↳ `open` | boolean | Whether the ticket is open |
| ↳ `is_shared` | boolean | Whether the ticket is visible to users |
| ↳ `snoozed_until` | number | Unix timestamp when ticket will reopen |
| ↳ `admin_assignee_id` | string | ID of assigned admin |
| ↳ `team_assignee_id` | string | ID of assigned team |
| ↳ `created_at` | number | Unix timestamp when ticket was created |
| ↳ `updated_at` | number | Unix timestamp when ticket was last updated |
| `ticketId` | string | ID of the updated ticket |
| `ticket_state` | string | Current state of the ticket |
### `intercom_create_message`
Create and send a new admin-initiated message in Intercom. Returns API-aligned fields only.
@@ -680,4 +716,340 @@ Create and send a new admin-initiated message in Intercom. Returns API-aligned f
| `messageId` | string | ID of the created message |
| `success` | boolean | Operation success status |
### `intercom_list_admins`
Fetch a list of all admins for the workspace
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `admins` | array | Array of admin objects |
| ↳ `id` | string | Unique identifier for the admin |
| ↳ `type` | string | Object type \(admin\) |
| ↳ `name` | string | Name of the admin |
| ↳ `email` | string | Email of the admin |
| ↳ `job_title` | string | Job title of the admin |
| ↳ `away_mode_enabled` | boolean | Whether admin is in away mode |
| ↳ `away_mode_reassign` | boolean | Whether to reassign conversations when away |
| ↳ `has_inbox_seat` | boolean | Whether admin has a paid inbox seat |
| ↳ `team_ids` | array | List of team IDs the admin belongs to |
| ↳ `avatar` | object | Avatar information |
| ↳ `email_verified` | boolean | Whether email is verified |
| `type` | string | Object type \(admin.list\) |
### `intercom_close_conversation`
Close a conversation in Intercom
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `conversationId` | string | Yes | The ID of the conversation to close |
| `admin_id` | string | Yes | The ID of the admin performing the action |
| `body` | string | No | Optional closing message to add to the conversation |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `conversation` | object | The closed conversation object |
| ↳ `id` | string | Unique identifier for the conversation |
| ↳ `type` | string | Object type \(conversation\) |
| ↳ `state` | string | State of the conversation \(closed\) |
| ↳ `open` | boolean | Whether the conversation is open \(false\) |
| ↳ `read` | boolean | Whether the conversation has been read |
| ↳ `created_at` | number | Unix timestamp when conversation was created |
| ↳ `updated_at` | number | Unix timestamp when conversation was last updated |
| `conversationId` | string | ID of the closed conversation |
| `state` | string | State of the conversation \(closed\) |
### `intercom_open_conversation`
Open a closed or snoozed conversation in Intercom
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `conversationId` | string | Yes | The ID of the conversation to open |
| `admin_id` | string | Yes | The ID of the admin performing the action |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `conversation` | object | The opened conversation object |
| ↳ `id` | string | Unique identifier for the conversation |
| ↳ `type` | string | Object type \(conversation\) |
| ↳ `state` | string | State of the conversation \(open\) |
| ↳ `open` | boolean | Whether the conversation is open \(true\) |
| ↳ `read` | boolean | Whether the conversation has been read |
| ↳ `created_at` | number | Unix timestamp when conversation was created |
| ↳ `updated_at` | number | Unix timestamp when conversation was last updated |
| `conversationId` | string | ID of the opened conversation |
| `state` | string | State of the conversation \(open\) |
### `intercom_snooze_conversation`
Snooze a conversation to reopen at a future time
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `conversationId` | string | Yes | The ID of the conversation to snooze |
| `admin_id` | string | Yes | The ID of the admin performing the action |
| `snoozed_until` | number | Yes | Unix timestamp for when the conversation should reopen |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `conversation` | object | The snoozed conversation object |
| ↳ `id` | string | Unique identifier for the conversation |
| ↳ `type` | string | Object type \(conversation\) |
| ↳ `state` | string | State of the conversation \(snoozed\) |
| ↳ `open` | boolean | Whether the conversation is open |
| ↳ `snoozed_until` | number | Unix timestamp when conversation will reopen |
| ↳ `created_at` | number | Unix timestamp when conversation was created |
| ↳ `updated_at` | number | Unix timestamp when conversation was last updated |
| `conversationId` | string | ID of the snoozed conversation |
| `state` | string | State of the conversation \(snoozed\) |
| `snoozed_until` | number | Unix timestamp when conversation will reopen |
### `intercom_assign_conversation`
Assign a conversation to an admin or team in Intercom
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `conversationId` | string | Yes | The ID of the conversation to assign |
| `admin_id` | string | Yes | The ID of the admin performing the assignment |
| `assignee_id` | string | Yes | The ID of the admin or team to assign the conversation to. Set to "0" to unassign. |
| `body` | string | No | Optional message to add when assigning \(e.g., "Passing to the support team"\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `conversation` | object | The assigned conversation object |
| ↳ `id` | string | Unique identifier for the conversation |
| ↳ `type` | string | Object type \(conversation\) |
| ↳ `state` | string | State of the conversation |
| ↳ `open` | boolean | Whether the conversation is open |
| ↳ `admin_assignee_id` | number | ID of the assigned admin |
| ↳ `team_assignee_id` | string | ID of the assigned team |
| ↳ `created_at` | number | Unix timestamp when conversation was created |
| ↳ `updated_at` | number | Unix timestamp when conversation was last updated |
| `conversationId` | string | ID of the assigned conversation |
| `admin_assignee_id` | number | ID of the assigned admin |
| `team_assignee_id` | string | ID of the assigned team |
### `intercom_list_tags`
Fetch a list of all tags in the workspace
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `tags` | array | Array of tag objects |
| ↳ `id` | string | Unique identifier for the tag |
| ↳ `type` | string | Object type \(tag\) |
| ↳ `name` | string | Name of the tag |
| `type` | string | Object type \(list\) |
### `intercom_create_tag`
Create a new tag or update an existing tag name
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `name` | string | Yes | The name of the tag. Will create a new tag if not found, or update the name if id is provided. |
| `id` | string | No | The ID of an existing tag to update. Omit to create a new tag. |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `id` | string | Unique identifier for the tag |
| `name` | string | Name of the tag |
| `type` | string | Object type \(tag\) |
### `intercom_tag_contact`
Add a tag to a specific contact
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `contactId` | string | Yes | The ID of the contact to tag |
| `tagId` | string | Yes | The ID of the tag to apply |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `id` | string | Unique identifier for the tag |
| `name` | string | Name of the tag |
| `type` | string | Object type \(tag\) |
### `intercom_untag_contact`
Remove a tag from a specific contact
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `contactId` | string | Yes | The ID of the contact to untag |
| `tagId` | string | Yes | The ID of the tag to remove |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `id` | string | Unique identifier for the tag that was removed |
| `name` | string | Name of the tag that was removed |
| `type` | string | Object type \(tag\) |
### `intercom_tag_conversation`
Add a tag to a specific conversation
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `conversationId` | string | Yes | The ID of the conversation to tag |
| `tagId` | string | Yes | The ID of the tag to apply |
| `admin_id` | string | Yes | The ID of the admin applying the tag |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `id` | string | Unique identifier for the tag |
| `name` | string | Name of the tag |
| `type` | string | Object type \(tag\) |
### `intercom_create_note`
Add a note to a specific contact
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `contactId` | string | Yes | The ID of the contact to add the note to |
| `body` | string | Yes | The text content of the note |
| `admin_id` | string | No | The ID of the admin creating the note |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `id` | string | Unique identifier for the note |
| `body` | string | The text content of the note |
| `created_at` | number | Unix timestamp when the note was created |
| `type` | string | Object type \(note\) |
| `author` | object | The admin who created the note |
| ↳ `type` | string | Author type \(admin\) |
| ↳ `id` | string | Author ID |
| ↳ `name` | string | Author name |
| ↳ `email` | string | Author email |
| `contact` | object | The contact the note was created for |
| ↳ `type` | string | Contact type |
| ↳ `id` | string | Contact ID |
### `intercom_create_event`
Track a custom event for a contact in Intercom
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `event_name` | string | Yes | The name of the event \(e.g., "order-completed"\). Use past-tense verb-noun format for readability. |
| `created_at` | number | No | Unix timestamp for when the event occurred. Strongly recommended for uniqueness. |
| `user_id` | string | No | Your identifier for the user \(external_id\) |
| `email` | string | No | Email address of the user. Use only if your app uses email to uniquely identify users. |
| `id` | string | No | The Intercom contact ID |
| `metadata` | string | No | JSON object with up to 10 metadata key-value pairs about the event \(e.g., \{"order_value": 99.99\}\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `accepted` | boolean | Whether the event was accepted \(202 Accepted\) |
### `intercom_attach_contact_to_company`
Attach a contact to a company in Intercom
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `contactId` | string | Yes | The ID of the contact to attach to the company |
| `companyId` | string | Yes | The ID of the company to attach the contact to |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `company` | object | The company object the contact was attached to |
| ↳ `id` | string | Unique identifier for the company |
| ↳ `type` | string | Object type \(company\) |
| ↳ `company_id` | string | The company_id you defined |
| ↳ `name` | string | Name of the company |
| ↳ `created_at` | number | Unix timestamp when company was created |
| ↳ `updated_at` | number | Unix timestamp when company was updated |
| ↳ `user_count` | number | Number of users in the company |
| ↳ `session_count` | number | Number of sessions |
| ↳ `monthly_spend` | number | Monthly spend amount |
| ↳ `plan` | object | Company plan details |
| `companyId` | string | ID of the company |
| `name` | string | Name of the company |
### `intercom_detach_contact_from_company`
Remove a contact from a company in Intercom
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `contactId` | string | Yes | The ID of the contact to detach from the company |
| `companyId` | string | Yes | The ID of the company to detach the contact from |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `company` | object | The company object the contact was detached from |
| ↳ `id` | string | Unique identifier for the company |
| ↳ `type` | string | Object type \(company\) |
| ↳ `company_id` | string | The company_id you defined |
| ↳ `name` | string | Name of the company |
| `companyId` | string | ID of the company |
| `name` | string | Name of the company |

View File

@@ -58,7 +58,6 @@ export function ExecutionSnapshot({
onClose = () => {},
}: ExecutionSnapshotProps) {
const { data, isLoading, error } = useExecutionSnapshot(executionId)
const lastExecutionIdRef = useRef<string | null>(null)
const [isMenuOpen, setIsMenuOpen] = useState(false)
const [menuPosition, setMenuPosition] = useState({ x: 0, y: 0 })
@@ -82,12 +81,6 @@ export function ExecutionSnapshot({
const workflowState = data?.workflowState as WorkflowState | undefined
// Track execution ID changes for key reset
const executionKey = executionId !== lastExecutionIdRef.current ? executionId : undefined
if (executionId !== lastExecutionIdRef.current) {
lastExecutionIdRef.current = executionId
}
const renderContent = () => {
if (isLoading) {
return (
@@ -152,7 +145,7 @@ export function ExecutionSnapshot({
return (
<Preview
key={executionKey}
key={executionId}
workflowState={workflowState}
traceSpans={traceSpans}
className={className}

View File

@@ -36,7 +36,22 @@ export const IntercomBlock: BlockConfig = {
{ label: 'Search Conversations', id: 'search_conversations' },
{ label: 'Create Ticket', id: 'create_ticket' },
{ label: 'Get Ticket', id: 'get_ticket' },
{ label: 'Update Ticket', id: 'update_ticket' },
{ label: 'Create Message', id: 'create_message' },
{ label: 'List Admins', id: 'list_admins' },
{ label: 'Close Conversation', id: 'close_conversation' },
{ label: 'Open Conversation', id: 'open_conversation' },
{ label: 'Snooze Conversation', id: 'snooze_conversation' },
{ label: 'Assign Conversation', id: 'assign_conversation' },
{ label: 'List Tags', id: 'list_tags' },
{ label: 'Create Tag', id: 'create_tag' },
{ label: 'Tag Contact', id: 'tag_contact' },
{ label: 'Untag Contact', id: 'untag_contact' },
{ label: 'Tag Conversation', id: 'tag_conversation' },
{ label: 'Create Note', id: 'create_note' },
{ label: 'Create Event', id: 'create_event' },
{ label: 'Attach Contact to Company', id: 'attach_contact_to_company' },
{ label: 'Detach Contact from Company', id: 'detach_contact_from_company' },
],
value: () => 'create_contact',
},
@@ -384,7 +399,15 @@ Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
required: true,
condition: {
field: 'operation',
value: ['get_conversation', 'reply_conversation'],
value: [
'get_conversation',
'reply_conversation',
'close_conversation',
'open_conversation',
'snooze_conversation',
'assign_conversation',
'tag_conversation',
],
},
},
{
@@ -477,11 +500,20 @@ Return ONLY the message text - no explanations.`,
id: 'admin_id',
title: 'Admin ID',
type: 'short-input',
placeholder: 'ID of the admin sending the message',
placeholder: 'ID of the admin performing the action',
required: true,
condition: {
field: 'operation',
value: ['reply_conversation'],
value: [
'reply_conversation',
'close_conversation',
'open_conversation',
'snooze_conversation',
'assign_conversation',
'tag_conversation',
'create_note',
'update_ticket',
],
},
},
{
@@ -526,7 +558,7 @@ Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
required: true,
condition: {
field: 'operation',
value: ['get_ticket'],
value: ['get_ticket', 'update_ticket'],
},
},
{
@@ -799,6 +831,307 @@ Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
value: ['list_companies'],
},
},
// Close/Open conversation body
{
id: 'close_body',
title: 'Closing Message',
type: 'long-input',
placeholder: 'Optional message to add when closing',
condition: {
field: 'operation',
value: ['close_conversation'],
},
},
// Snooze conversation
{
id: 'snoozed_until',
title: 'Snooze Until',
type: 'short-input',
placeholder: 'Unix timestamp when conversation should reopen',
required: true,
condition: {
field: 'operation',
value: ['snooze_conversation'],
},
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp in seconds based on the user's description.
The timestamp should be a Unix epoch time in seconds (10 digits).
Examples:
- "tomorrow" -> Tomorrow at 09:00:00 as Unix timestamp
- "in 2 hours" -> Current time plus 7200 seconds
- "next Monday" -> Next Monday at 09:00:00 as Unix timestamp
Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
placeholder: 'Describe when to unsnooze (e.g., "tomorrow", "in 2 hours")...',
generationType: 'timestamp',
},
},
// Assign conversation
{
id: 'assignee_id',
title: 'Assignee ID',
type: 'short-input',
placeholder: 'Admin or team ID to assign to (0 to unassign)',
required: true,
condition: {
field: 'operation',
value: ['assign_conversation'],
},
},
{
id: 'assign_body',
title: 'Assignment Message',
type: 'long-input',
placeholder: 'Optional message when assigning',
condition: {
field: 'operation',
value: ['assign_conversation'],
},
},
// Update ticket fields
{
id: 'update_ticket_attributes',
title: 'Ticket Attributes',
type: 'long-input',
placeholder: 'JSON object with ticket attributes to update',
condition: {
field: 'operation',
value: ['update_ticket'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON object for Intercom ticket attributes based on the user's description.
Example: {"_default_title_": "Updated title", "_default_description_": "Updated description"}
Return ONLY the JSON object - no explanations or markdown formatting.`,
placeholder: 'Describe the ticket updates (e.g., "change title to Bug Fixed")...',
generationType: 'json-object',
},
},
{
id: 'ticket_open',
title: 'Ticket Open',
type: 'dropdown',
options: [
{ label: 'Keep Open', id: 'true' },
{ label: 'Close Ticket', id: 'false' },
],
condition: {
field: 'operation',
value: ['update_ticket'],
},
},
{
id: 'ticket_is_shared',
title: 'Ticket Visible to Users',
type: 'dropdown',
options: [
{ label: 'Yes', id: 'true' },
{ label: 'No', id: 'false' },
],
condition: {
field: 'operation',
value: ['update_ticket'],
},
},
{
id: 'ticket_snoozed_until',
title: 'Snooze Ticket Until',
type: 'short-input',
placeholder: 'Unix timestamp when ticket should reopen',
condition: {
field: 'operation',
value: ['update_ticket'],
},
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp in seconds based on the user's description.
Examples:
- "tomorrow" -> Tomorrow at 09:00:00 as Unix timestamp
- "next week" -> 7 days from now
Return ONLY the numeric timestamp.`,
placeholder: 'Describe when to unsnooze (e.g., "tomorrow")...',
generationType: 'timestamp',
},
},
{
id: 'ticket_assignee_id',
title: 'Ticket Assignee ID',
type: 'short-input',
placeholder: 'Admin or team ID to assign to (0 to unassign)',
condition: {
field: 'operation',
value: ['update_ticket'],
},
},
// Tag fields
{
id: 'tagId',
title: 'Tag ID',
type: 'short-input',
placeholder: 'ID of the tag',
required: true,
condition: {
field: 'operation',
value: ['tag_contact', 'untag_contact', 'tag_conversation'],
},
},
{
id: 'tag_name',
title: 'Tag Name',
type: 'short-input',
placeholder: 'Name of the tag to create',
required: true,
condition: {
field: 'operation',
value: ['create_tag'],
},
},
{
id: 'tag_id_update',
title: 'Tag ID (for update)',
type: 'short-input',
placeholder: 'ID of existing tag to update (leave empty to create new)',
condition: {
field: 'operation',
value: ['create_tag'],
},
},
// Contact ID for tag/untag/note operations
{
id: 'tag_contact_id',
title: 'Contact ID',
type: 'short-input',
placeholder: 'ID of the contact',
required: true,
condition: {
field: 'operation',
value: [
'tag_contact',
'untag_contact',
'create_note',
'attach_contact_to_company',
'detach_contact_from_company',
],
},
},
// Note fields
{
id: 'note_body',
title: 'Note Content',
type: 'long-input',
placeholder: 'Text content of the note',
required: true,
condition: {
field: 'operation',
value: ['create_note'],
},
wandConfig: {
enabled: true,
prompt: `Generate a note for Intercom based on the user's description.
The note should be clear, professional, and capture the key information.
Return ONLY the note text - no explanations.`,
placeholder: 'Describe the note content (e.g., "customer requested callback")...',
},
},
// Event fields
{
id: 'event_name',
title: 'Event Name',
type: 'short-input',
placeholder: 'Event name (e.g., order-completed)',
required: true,
condition: {
field: 'operation',
value: ['create_event'],
},
},
{
id: 'event_user_id',
title: 'User ID',
type: 'short-input',
placeholder: 'Your identifier for the user',
condition: {
field: 'operation',
value: ['create_event'],
},
},
{
id: 'event_email',
title: 'User Email',
type: 'short-input',
placeholder: 'Email address of the user',
condition: {
field: 'operation',
value: ['create_event'],
},
},
{
id: 'event_contact_id',
title: 'Contact ID',
type: 'short-input',
placeholder: 'Intercom contact ID',
condition: {
field: 'operation',
value: ['create_event'],
},
},
{
id: 'event_metadata',
title: 'Event Metadata',
type: 'long-input',
placeholder: 'JSON object with event metadata (max 10 keys)',
condition: {
field: 'operation',
value: ['create_event'],
},
wandConfig: {
enabled: true,
prompt: `Generate a JSON object for Intercom event metadata based on the user's description.
The object should contain key-value pairs (max 10 keys).
Example: {"order_value": 99.99, "items": 3, "coupon_used": true}
Return ONLY the JSON object - no explanations or markdown formatting.`,
placeholder: 'Describe the event data (e.g., "order value $50, 2 items")...',
generationType: 'json-object',
},
},
{
id: 'event_created_at',
title: 'Event Time',
type: 'short-input',
placeholder: 'Unix timestamp when event occurred',
condition: {
field: 'operation',
value: ['create_event'],
},
wandConfig: {
enabled: true,
prompt: `Generate a Unix timestamp in seconds based on the user's description.
Examples:
- "now" -> Current Unix timestamp
- "5 minutes ago" -> Current time minus 300 seconds
Return ONLY the numeric timestamp.`,
placeholder: 'Describe when the event occurred (e.g., "now")...',
generationType: 'timestamp',
},
},
// Company attachment fields
{
id: 'attach_company_id',
title: 'Company ID',
type: 'short-input',
placeholder: 'ID of the company to attach/detach',
required: true,
condition: {
field: 'operation',
value: ['attach_contact_to_company', 'detach_contact_from_company'],
},
},
],
tools: {
access: [
@@ -818,6 +1151,21 @@ Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
'intercom_create_ticket',
'intercom_get_ticket',
'intercom_create_message',
'intercom_update_ticket_v2',
'intercom_list_admins_v2',
'intercom_close_conversation_v2',
'intercom_open_conversation_v2',
'intercom_snooze_conversation_v2',
'intercom_assign_conversation_v2',
'intercom_list_tags_v2',
'intercom_create_tag_v2',
'intercom_tag_contact_v2',
'intercom_untag_contact_v2',
'intercom_tag_conversation_v2',
'intercom_create_note_v2',
'intercom_create_event_v2',
'intercom_attach_contact_to_company_v2',
'intercom_detach_contact_from_company_v2',
],
config: {
tool: (params) => {
@@ -854,6 +1202,36 @@ Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
return 'intercom_get_ticket'
case 'create_message':
return 'intercom_create_message'
case 'update_ticket':
return 'intercom_update_ticket_v2'
case 'list_admins':
return 'intercom_list_admins_v2'
case 'close_conversation':
return 'intercom_close_conversation_v2'
case 'open_conversation':
return 'intercom_open_conversation_v2'
case 'snooze_conversation':
return 'intercom_snooze_conversation_v2'
case 'assign_conversation':
return 'intercom_assign_conversation_v2'
case 'list_tags':
return 'intercom_list_tags_v2'
case 'create_tag':
return 'intercom_create_tag_v2'
case 'tag_contact':
return 'intercom_tag_contact_v2'
case 'untag_contact':
return 'intercom_untag_contact_v2'
case 'tag_conversation':
return 'intercom_tag_conversation_v2'
case 'create_note':
return 'intercom_create_note_v2'
case 'create_event':
return 'intercom_create_event_v2'
case 'attach_contact_to_company':
return 'intercom_attach_contact_to_company_v2'
case 'detach_contact_from_company':
return 'intercom_detach_contact_from_company_v2'
default:
throw new Error(`Unknown operation: ${params.operation}`)
}
@@ -870,6 +1248,23 @@ Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
message_created_at,
include_translations,
disable_notifications,
close_body,
assign_body,
tag_contact_id,
attach_company_id,
update_ticket_attributes,
ticket_open,
ticket_is_shared,
ticket_snoozed_until,
ticket_assignee_id,
tag_name,
tag_id_update,
note_body,
event_user_id,
event_email,
event_contact_id,
event_metadata,
event_created_at,
...rest
} = params
const cleanParams: Record<string, any> = {}
@@ -897,7 +1292,7 @@ Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
cleanParams.created_at = Number(reply_created_at)
}
// Map ticket fields
// Map ticket fields for create_ticket
if (operation === 'create_ticket') {
if (ticket_company_id) cleanParams.company_id = ticket_company_id
if (ticket_created_at) cleanParams.created_at = Number(ticket_created_at)
@@ -920,6 +1315,71 @@ Return ONLY the numeric timestamp - no explanations, no quotes, no extra text.`,
cleanParams.include_translations = include_translations === 'true'
}
// Map close_body to body for close_conversation
if (operation === 'close_conversation' && close_body) {
cleanParams.body = close_body
}
// Map assign_body to body for assign_conversation
if (operation === 'assign_conversation' && assign_body) {
cleanParams.body = assign_body
}
// Map tag_contact_id to contactId for tag/note/company attachment operations
if (
[
'tag_contact',
'untag_contact',
'create_note',
'attach_contact_to_company',
'detach_contact_from_company',
].includes(operation) &&
tag_contact_id
) {
cleanParams.contactId = tag_contact_id
}
// Map attach_company_id to companyId for company attachment operations
if (
['attach_contact_to_company', 'detach_contact_from_company'].includes(operation) &&
attach_company_id
) {
cleanParams.companyId = attach_company_id
}
// Map update_ticket fields
if (operation === 'update_ticket') {
if (update_ticket_attributes) cleanParams.ticket_attributes = update_ticket_attributes
if (ticket_open !== undefined && ticket_open !== '') {
cleanParams.open = ticket_open === 'true'
}
if (ticket_is_shared !== undefined && ticket_is_shared !== '') {
cleanParams.is_shared = ticket_is_shared === 'true'
}
if (ticket_snoozed_until) cleanParams.snoozed_until = Number(ticket_snoozed_until)
if (ticket_assignee_id) cleanParams.assignee_id = ticket_assignee_id
}
// Map tag fields for create_tag
if (operation === 'create_tag') {
if (tag_name) cleanParams.name = tag_name
if (tag_id_update) cleanParams.id = tag_id_update
}
// Map note_body to body for create_note
if (operation === 'create_note' && note_body) {
cleanParams.body = note_body
}
// Map event fields for create_event
if (operation === 'create_event') {
if (event_user_id) cleanParams.user_id = event_user_id
if (event_email) cleanParams.email = event_email
if (event_contact_id) cleanParams.id = event_contact_id
if (event_metadata) cleanParams.metadata = event_metadata
if (event_created_at) cleanParams.created_at = Number(event_created_at)
}
Object.entries(rest).forEach(([key, value]) => {
if (value !== undefined && value !== null && value !== '') {
cleanParams[key] = value
@@ -963,7 +1423,22 @@ export const IntercomV2Block: BlockConfig = {
'intercom_search_conversations_v2',
'intercom_create_ticket_v2',
'intercom_get_ticket_v2',
'intercom_update_ticket_v2',
'intercom_create_message_v2',
'intercom_list_admins_v2',
'intercom_close_conversation_v2',
'intercom_open_conversation_v2',
'intercom_snooze_conversation_v2',
'intercom_assign_conversation_v2',
'intercom_list_tags_v2',
'intercom_create_tag_v2',
'intercom_tag_contact_v2',
'intercom_untag_contact_v2',
'intercom_tag_conversation_v2',
'intercom_create_note_v2',
'intercom_create_event_v2',
'intercom_attach_contact_to_company_v2',
'intercom_detach_contact_from_company_v2',
],
config: {
tool: createVersionedToolSelector({
@@ -999,8 +1474,38 @@ export const IntercomV2Block: BlockConfig = {
return 'intercom_create_ticket'
case 'get_ticket':
return 'intercom_get_ticket'
case 'update_ticket':
return 'intercom_update_ticket'
case 'create_message':
return 'intercom_create_message'
case 'list_admins':
return 'intercom_list_admins'
case 'close_conversation':
return 'intercom_close_conversation'
case 'open_conversation':
return 'intercom_open_conversation'
case 'snooze_conversation':
return 'intercom_snooze_conversation'
case 'assign_conversation':
return 'intercom_assign_conversation'
case 'list_tags':
return 'intercom_list_tags'
case 'create_tag':
return 'intercom_create_tag'
case 'tag_contact':
return 'intercom_tag_contact'
case 'untag_contact':
return 'intercom_untag_contact'
case 'tag_conversation':
return 'intercom_tag_conversation'
case 'create_note':
return 'intercom_create_note'
case 'create_event':
return 'intercom_create_event'
case 'attach_contact_to_company':
return 'intercom_attach_contact_to_company'
case 'detach_contact_from_company':
return 'intercom_detach_contact_from_company'
default:
return 'intercom_create_contact'
}
@@ -1008,7 +1513,158 @@ export const IntercomV2Block: BlockConfig = {
suffix: '_v2',
fallbackToolId: 'intercom_create_contact_v2',
}),
params: IntercomBlock.tools!.config!.params,
params: (params) => {
const {
operation,
message_type_msg,
company_name,
contact_company_id,
reply_created_at,
ticket_company_id,
ticket_created_at,
message_created_at,
include_translations,
disable_notifications,
close_body,
assign_body,
tag_contact_id,
attach_company_id,
update_ticket_attributes,
ticket_open,
ticket_is_shared,
ticket_snoozed_until,
ticket_assignee_id,
tag_name,
tag_id_update,
note_body,
event_user_id,
event_email,
event_contact_id,
event_metadata,
event_created_at,
...rest
} = params
const cleanParams: Record<string, any> = {}
// Special mapping for message_type in create_message
if (operation === 'create_message' && message_type_msg) {
cleanParams.message_type = message_type_msg
}
// Special mapping for company name
if (operation === 'create_company' && company_name) {
cleanParams.name = company_name
}
// Map contact_company_id to company_id for contact operations
if (
(operation === 'create_contact' || operation === 'update_contact') &&
contact_company_id
) {
cleanParams.company_id = contact_company_id
}
// Map reply_created_at to created_at for reply_conversation
if (operation === 'reply_conversation' && reply_created_at) {
cleanParams.created_at = Number(reply_created_at)
}
// Map ticket fields for create_ticket
if (operation === 'create_ticket') {
if (ticket_company_id) cleanParams.company_id = ticket_company_id
if (ticket_created_at) cleanParams.created_at = Number(ticket_created_at)
if (disable_notifications !== undefined && disable_notifications !== '') {
cleanParams.disable_notifications = disable_notifications === 'true'
}
}
// Map message_created_at to created_at for create_message
if (operation === 'create_message' && message_created_at) {
cleanParams.created_at = Number(message_created_at)
}
// Convert include_translations string to boolean for get_conversation
if (
operation === 'get_conversation' &&
include_translations !== undefined &&
include_translations !== ''
) {
cleanParams.include_translations = include_translations === 'true'
}
// Map close_body to body for close_conversation
if (operation === 'close_conversation' && close_body) {
cleanParams.body = close_body
}
// Map assign_body to body for assign_conversation
if (operation === 'assign_conversation' && assign_body) {
cleanParams.body = assign_body
}
// Map tag_contact_id to contactId for tag/note/company attachment operations
if (
[
'tag_contact',
'untag_contact',
'create_note',
'attach_contact_to_company',
'detach_contact_from_company',
].includes(operation) &&
tag_contact_id
) {
cleanParams.contactId = tag_contact_id
}
// Map attach_company_id to companyId for company attachment operations
if (
['attach_contact_to_company', 'detach_contact_from_company'].includes(operation) &&
attach_company_id
) {
cleanParams.companyId = attach_company_id
}
// Map update_ticket fields
if (operation === 'update_ticket') {
if (update_ticket_attributes) cleanParams.ticket_attributes = update_ticket_attributes
if (ticket_open !== undefined && ticket_open !== '') {
cleanParams.open = ticket_open === 'true'
}
if (ticket_is_shared !== undefined && ticket_is_shared !== '') {
cleanParams.is_shared = ticket_is_shared === 'true'
}
if (ticket_snoozed_until) cleanParams.snoozed_until = Number(ticket_snoozed_until)
if (ticket_assignee_id) cleanParams.assignee_id = ticket_assignee_id
}
// Map tag fields for create_tag
if (operation === 'create_tag') {
if (tag_name) cleanParams.name = tag_name
if (tag_id_update) cleanParams.id = tag_id_update
}
// Map note_body to body for create_note
if (operation === 'create_note' && note_body) {
cleanParams.body = note_body
}
// Map event fields for create_event
if (operation === 'create_event') {
if (event_user_id) cleanParams.user_id = event_user_id
if (event_email) cleanParams.email = event_email
if (event_contact_id) cleanParams.id = event_contact_id
if (event_metadata) cleanParams.metadata = event_metadata
if (event_created_at) cleanParams.created_at = Number(event_created_at)
}
Object.entries(rest).forEach(([key, value]) => {
if (value !== undefined && value !== null && value !== '') {
cleanParams[key] = value
}
})
return cleanParams
},
},
},
outputs: {
@@ -1031,10 +1687,23 @@ export const IntercomV2Block: BlockConfig = {
type: 'array',
description: 'Array of conversations (for list/search operations)',
},
state: { type: 'string', description: 'Conversation state (for close/open/snooze operations)' },
ticket: { type: 'json', description: 'Ticket object with id, ticket_id, ticket_state' },
ticketId: { type: 'string', description: 'ID of the ticket (for create operations)' },
ticketId: { type: 'string', description: 'ID of the ticket (for create/update operations)' },
ticket_state: { type: 'string', description: 'Ticket state (for update_ticket operation)' },
message: { type: 'json', description: 'Message object with id, type' },
messageId: { type: 'string', description: 'ID of the message (for create operations)' },
admins: { type: 'array', description: 'Array of admin objects (for list_admins operation)' },
tags: { type: 'array', description: 'Array of tag objects (for list_tags operation)' },
tag: { type: 'json', description: 'Tag object with id and name (for tag operations)' },
tagId: { type: 'string', description: 'ID of the tag (for create_tag operation)' },
note: { type: 'json', description: 'Note object with id and body (for create_note operation)' },
noteId: { type: 'string', description: 'ID of the note (for create_note operation)' },
event_name: {
type: 'string',
description: 'Name of the tracked event (for create_event operation)',
},
name: { type: 'string', description: 'Name of the resource (for various operations)' },
total_count: { type: 'number', description: 'Total count (for list/search operations)' },
pages: { type: 'json', description: 'Pagination info with page, per_page, total_pages' },
id: { type: 'string', description: 'ID of the deleted item (for delete operations)' },

View File

@@ -0,0 +1,146 @@
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
export interface IntercomAssignConversationParams {
accessToken: string
conversationId: string
admin_id: string
assignee_id: string
body?: string
}
export interface IntercomAssignConversationV2Response {
success: boolean
output: {
conversation: any
conversationId: string
admin_assignee_id: number | null
team_assignee_id: string | null
}
}
const assignConversationBase = {
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Intercom API access token',
},
conversationId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the conversation to assign',
},
admin_id: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the admin performing the assignment',
},
assignee_id: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description:
'The ID of the admin or team to assign the conversation to. Set to "0" to unassign.',
},
body: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Optional message to add when assigning (e.g., "Passing to the support team")',
},
},
request: {
url: (params: IntercomAssignConversationParams) =>
buildIntercomUrl(`/conversations/${params.conversationId}/parts`),
method: 'POST',
headers: (params: IntercomAssignConversationParams) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'Intercom-Version': '2.14',
}),
body: (params: IntercomAssignConversationParams) => {
const payload: any = {
message_type: 'assignment',
type: 'admin',
admin_id: params.admin_id,
assignee_id: params.assignee_id,
}
if (params.body) {
payload.body = params.body
}
return payload
},
},
} satisfies Pick<ToolConfig<IntercomAssignConversationParams, any>, 'params' | 'request'>
export const intercomAssignConversationV2Tool: ToolConfig<
IntercomAssignConversationParams,
IntercomAssignConversationV2Response
> = {
...assignConversationBase,
id: 'intercom_assign_conversation_v2',
name: 'Assign Conversation in Intercom',
description: 'Assign a conversation to an admin or team in Intercom',
version: '2.0.0',
transformResponse: async (response: Response) => {
if (!response.ok) {
const data = await response.json()
handleIntercomError(data, response.status, 'assign_conversation')
}
const data = await response.json()
return {
success: true,
output: {
conversation: data,
conversationId: data.id,
admin_assignee_id: data.admin_assignee_id ?? null,
team_assignee_id: data.team_assignee_id ?? null,
},
}
},
outputs: {
conversation: {
type: 'object',
description: 'The assigned conversation object',
properties: {
id: { type: 'string', description: 'Unique identifier for the conversation' },
type: { type: 'string', description: 'Object type (conversation)' },
state: { type: 'string', description: 'State of the conversation' },
open: { type: 'boolean', description: 'Whether the conversation is open' },
admin_assignee_id: {
type: 'number',
description: 'ID of the assigned admin',
optional: true,
},
team_assignee_id: {
type: 'string',
description: 'ID of the assigned team',
optional: true,
},
created_at: { type: 'number', description: 'Unix timestamp when conversation was created' },
updated_at: {
type: 'number',
description: 'Unix timestamp when conversation was last updated',
},
},
},
conversationId: { type: 'string', description: 'ID of the assigned conversation' },
admin_assignee_id: {
type: 'number',
description: 'ID of the assigned admin',
optional: true,
},
team_assignee_id: { type: 'string', description: 'ID of the assigned team', optional: true },
},
}

View File

@@ -0,0 +1,115 @@
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
export interface IntercomAttachContactToCompanyParams {
accessToken: string
contactId: string
companyId: string
}
export interface IntercomAttachContactToCompanyV2Response {
success: boolean
output: {
company: any
companyId: string
name: string | null
}
}
const attachContactToCompanyBase = {
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Intercom API access token',
},
contactId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the contact to attach to the company',
},
companyId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the company to attach the contact to',
},
},
request: {
url: (params: IntercomAttachContactToCompanyParams) =>
buildIntercomUrl(`/contacts/${params.contactId}/companies`),
method: 'POST',
headers: (params: IntercomAttachContactToCompanyParams) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'Intercom-Version': '2.14',
}),
body: (params: IntercomAttachContactToCompanyParams) => ({
id: params.companyId,
}),
},
} satisfies Pick<ToolConfig<IntercomAttachContactToCompanyParams, any>, 'params' | 'request'>
export const intercomAttachContactToCompanyV2Tool: ToolConfig<
IntercomAttachContactToCompanyParams,
IntercomAttachContactToCompanyV2Response
> = {
...attachContactToCompanyBase,
id: 'intercom_attach_contact_to_company_v2',
name: 'Attach Contact to Company in Intercom',
description: 'Attach a contact to a company in Intercom',
version: '2.0.0',
transformResponse: async (response: Response) => {
if (!response.ok) {
const data = await response.json()
handleIntercomError(data, response.status, 'attach_contact_to_company')
}
const data = await response.json()
return {
success: true,
output: {
company: {
id: data.id,
type: data.type ?? 'company',
company_id: data.company_id ?? null,
name: data.name ?? null,
created_at: data.created_at ?? null,
updated_at: data.updated_at ?? null,
user_count: data.user_count ?? null,
session_count: data.session_count ?? null,
monthly_spend: data.monthly_spend ?? null,
plan: data.plan ?? null,
},
companyId: data.id,
name: data.name ?? null,
},
}
},
outputs: {
company: {
type: 'object',
description: 'The company object the contact was attached to',
properties: {
id: { type: 'string', description: 'Unique identifier for the company' },
type: { type: 'string', description: 'Object type (company)' },
company_id: { type: 'string', description: 'The company_id you defined' },
name: { type: 'string', description: 'Name of the company' },
created_at: { type: 'number', description: 'Unix timestamp when company was created' },
updated_at: { type: 'number', description: 'Unix timestamp when company was updated' },
user_count: { type: 'number', description: 'Number of users in the company' },
session_count: { type: 'number', description: 'Number of sessions' },
monthly_spend: { type: 'number', description: 'Monthly spend amount' },
plan: { type: 'object', description: 'Company plan details' },
},
},
companyId: { type: 'string', description: 'ID of the company' },
name: { type: 'string', description: 'Name of the company', optional: true },
},
}

View File

@@ -0,0 +1,129 @@
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
export interface IntercomCloseConversationParams {
accessToken: string
conversationId: string
admin_id: string
body?: string
}
export interface IntercomCloseConversationV2Response {
success: boolean
output: {
conversation: any
conversationId: string
state: string
}
}
const closeConversationBase = {
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Intercom API access token',
},
conversationId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the conversation to close',
},
admin_id: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the admin performing the action',
},
body: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Optional closing message to add to the conversation',
},
},
request: {
url: (params: IntercomCloseConversationParams) =>
buildIntercomUrl(`/conversations/${params.conversationId}/parts`),
method: 'POST',
headers: (params: IntercomCloseConversationParams) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'Intercom-Version': '2.14',
}),
body: (params: IntercomCloseConversationParams) => {
const payload: any = {
message_type: 'close',
type: 'admin',
admin_id: params.admin_id,
}
if (params.body) {
payload.body = params.body
}
return payload
},
},
} satisfies Pick<ToolConfig<IntercomCloseConversationParams, any>, 'params' | 'request'>
export const intercomCloseConversationV2Tool: ToolConfig<
IntercomCloseConversationParams,
IntercomCloseConversationV2Response
> = {
...closeConversationBase,
id: 'intercom_close_conversation_v2',
name: 'Close Conversation in Intercom',
description: 'Close a conversation in Intercom',
version: '2.0.0',
transformResponse: async (response: Response) => {
if (!response.ok) {
const data = await response.json()
handleIntercomError(data, response.status, 'close_conversation')
}
const data = await response.json()
return {
success: true,
output: {
conversation: {
id: data.id,
type: data.type ?? 'conversation',
state: data.state ?? 'closed',
open: data.open ?? false,
read: data.read ?? false,
created_at: data.created_at ?? null,
updated_at: data.updated_at ?? null,
},
conversationId: data.id,
state: data.state ?? 'closed',
},
}
},
outputs: {
conversation: {
type: 'object',
description: 'The closed conversation object',
properties: {
id: { type: 'string', description: 'Unique identifier for the conversation' },
type: { type: 'string', description: 'Object type (conversation)' },
state: { type: 'string', description: 'State of the conversation (closed)' },
open: { type: 'boolean', description: 'Whether the conversation is open (false)' },
read: { type: 'boolean', description: 'Whether the conversation has been read' },
created_at: { type: 'number', description: 'Unix timestamp when conversation was created' },
updated_at: {
type: 'number',
description: 'Unix timestamp when conversation was last updated',
},
},
},
conversationId: { type: 'string', description: 'ID of the closed conversation' },
state: { type: 'string', description: 'State of the conversation (closed)' },
},
}

View File

@@ -1,6 +1,6 @@
import { createLogger } from '@sim/logger'
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
import { buildIntercomUrl, handleIntercomError } from './types'
const logger = createLogger('IntercomCreateCompany')
@@ -60,7 +60,7 @@ const createCompanyBase = {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
visibility: 'user-only',
description: 'Intercom API access token',
},
company_id: {

View File

@@ -1,6 +1,6 @@
import { createLogger } from '@sim/logger'
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
import { buildIntercomUrl, handleIntercomError } from './types'
const logger = createLogger('IntercomCreateContact')
@@ -88,7 +88,7 @@ const intercomCreateContactBase = {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
visibility: 'user-only',
description: 'Intercom API access token',
},
role: {

View File

@@ -0,0 +1,148 @@
import { createLogger } from '@sim/logger'
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
const logger = createLogger('IntercomCreateEvent')
export interface IntercomCreateEventParams {
accessToken: string
event_name: string
created_at?: number
user_id?: string
email?: string
id?: string
metadata?: string
}
export interface IntercomCreateEventV2Response {
success: boolean
output: {
accepted: boolean
}
}
const createEventBase = {
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Intercom API access token',
},
event_name: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description:
'The name of the event (e.g., "order-completed"). Use past-tense verb-noun format for readability.',
},
created_at: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description:
'Unix timestamp for when the event occurred. Strongly recommended for uniqueness.',
},
user_id: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Your identifier for the user (external_id)',
},
email: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'Email address of the user. Use only if your app uses email to uniquely identify users.',
},
id: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'The Intercom contact ID',
},
metadata: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'JSON object with up to 10 metadata key-value pairs about the event (e.g., {"order_value": 99.99})',
},
},
request: {
url: () => buildIntercomUrl('/events'),
method: 'POST',
headers: (params: IntercomCreateEventParams) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'Intercom-Version': '2.14',
}),
body: (params: IntercomCreateEventParams) => {
const payload: any = {
event_name: params.event_name,
}
if (params.created_at) {
payload.created_at = params.created_at
} else {
payload.created_at = Math.floor(Date.now() / 1000)
}
if (params.user_id) {
payload.user_id = params.user_id
}
if (params.email) {
payload.email = params.email
}
if (params.id) {
payload.id = params.id
}
if (params.metadata) {
try {
payload.metadata = JSON.parse(params.metadata)
} catch (error) {
logger.warn('Failed to parse metadata, ignoring', { error })
}
}
return payload
},
},
} satisfies Pick<ToolConfig<IntercomCreateEventParams, any>, 'params' | 'request'>
export const intercomCreateEventV2Tool: ToolConfig<
IntercomCreateEventParams,
IntercomCreateEventV2Response
> = {
...createEventBase,
id: 'intercom_create_event_v2',
name: 'Create Event in Intercom',
description: 'Track a custom event for a contact in Intercom',
version: '2.0.0',
transformResponse: async (response: Response) => {
if (!response.ok) {
const data = await response.json()
handleIntercomError(data, response.status, 'create_event')
}
return {
success: true,
output: {
accepted: true,
},
}
},
outputs: {
accepted: {
type: 'boolean',
description: 'Whether the event was accepted (202 Accepted)',
},
},
}

View File

@@ -1,5 +1,5 @@
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
import { buildIntercomUrl, handleIntercomError } from './types'
export interface IntercomCreateMessageParams {
accessToken: string
@@ -40,7 +40,7 @@ const createMessageBase = {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
visibility: 'user-only',
description: 'Intercom API access token',
},
message_type: {

View File

@@ -0,0 +1,131 @@
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
export interface IntercomCreateNoteParams {
accessToken: string
contactId: string
body: string
admin_id?: string
}
export interface IntercomCreateNoteV2Response {
success: boolean
output: {
id: string
body: string
created_at: number
type: string
author: any | null
contact: any | null
}
}
const createNoteBase = {
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Intercom API access token',
},
contactId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the contact to add the note to',
},
body: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The text content of the note',
},
admin_id: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'The ID of the admin creating the note',
},
},
request: {
url: (params: IntercomCreateNoteParams) =>
buildIntercomUrl(`/contacts/${params.contactId}/notes`),
method: 'POST',
headers: (params: IntercomCreateNoteParams) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'Intercom-Version': '2.14',
}),
body: (params: IntercomCreateNoteParams) => {
const payload: any = {
body: params.body,
}
if (params.admin_id) {
payload.admin_id = params.admin_id
}
return payload
},
},
} satisfies Pick<ToolConfig<IntercomCreateNoteParams, any>, 'params' | 'request'>
export const intercomCreateNoteV2Tool: ToolConfig<
IntercomCreateNoteParams,
IntercomCreateNoteV2Response
> = {
...createNoteBase,
id: 'intercom_create_note_v2',
name: 'Create Note in Intercom',
description: 'Add a note to a specific contact',
version: '2.0.0',
transformResponse: async (response: Response) => {
if (!response.ok) {
const data = await response.json()
handleIntercomError(data, response.status, 'create_note')
}
const data = await response.json()
return {
success: true,
output: {
id: data.id,
body: data.body,
created_at: data.created_at,
type: data.type ?? 'note',
author: data.author ?? null,
contact: data.contact ?? null,
},
}
},
outputs: {
id: { type: 'string', description: 'Unique identifier for the note' },
body: { type: 'string', description: 'The text content of the note' },
created_at: { type: 'number', description: 'Unix timestamp when the note was created' },
type: { type: 'string', description: 'Object type (note)' },
author: {
type: 'object',
description: 'The admin who created the note',
optional: true,
properties: {
type: { type: 'string', description: 'Author type (admin)' },
id: { type: 'string', description: 'Author ID' },
name: { type: 'string', description: 'Author name' },
email: { type: 'string', description: 'Author email' },
},
},
contact: {
type: 'object',
description: 'The contact the note was created for',
optional: true,
properties: {
type: { type: 'string', description: 'Contact type' },
id: { type: 'string', description: 'Contact ID' },
},
},
},
}

View File

@@ -0,0 +1,97 @@
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
export interface IntercomCreateTagParams {
accessToken: string
name: string
id?: string
}
export interface IntercomCreateTagV2Response {
success: boolean
output: {
id: string
name: string
type: string
}
}
const createTagBase = {
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Intercom API access token',
},
name: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description:
'The name of the tag. Will create a new tag if not found, or update the name if id is provided.',
},
id: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'The ID of an existing tag to update. Omit to create a new tag.',
},
},
request: {
url: () => buildIntercomUrl('/tags'),
method: 'POST',
headers: (params: IntercomCreateTagParams) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'Intercom-Version': '2.14',
}),
body: (params: IntercomCreateTagParams) => {
const payload: any = {
name: params.name,
}
if (params.id) {
payload.id = params.id
}
return payload
},
},
} satisfies Pick<ToolConfig<IntercomCreateTagParams, any>, 'params' | 'request'>
export const intercomCreateTagV2Tool: ToolConfig<
IntercomCreateTagParams,
IntercomCreateTagV2Response
> = {
...createTagBase,
id: 'intercom_create_tag_v2',
name: 'Create Tag in Intercom',
description: 'Create a new tag or update an existing tag name',
version: '2.0.0',
transformResponse: async (response: Response) => {
if (!response.ok) {
const data = await response.json()
handleIntercomError(data, response.status, 'create_tag')
}
const data = await response.json()
return {
success: true,
output: {
id: data.id,
name: data.name,
type: data.type ?? 'tag',
},
}
},
outputs: {
id: { type: 'string', description: 'Unique identifier for the tag' },
name: { type: 'string', description: 'Name of the tag' },
type: { type: 'string', description: 'Object type (tag)' },
},
}

View File

@@ -1,6 +1,6 @@
import { createLogger } from '@sim/logger'
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
import { buildIntercomUrl, handleIntercomError } from './types'
const logger = createLogger('IntercomCreateTicket')
@@ -41,7 +41,7 @@ const createTicketBase = {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
visibility: 'user-only',
description: 'Intercom API access token',
},
ticket_type_id: {

View File

@@ -1,5 +1,5 @@
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
import { buildIntercomUrl, handleIntercomError } from './types'
export interface IntercomDeleteContactParams {
accessToken: string
@@ -23,7 +23,7 @@ const intercomDeleteContactBase = {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
visibility: 'user-only',
description: 'Intercom API access token',
},
contactId: {

View File

@@ -0,0 +1,101 @@
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
export interface IntercomDetachContactFromCompanyParams {
accessToken: string
contactId: string
companyId: string
}
export interface IntercomDetachContactFromCompanyV2Response {
success: boolean
output: {
company: any
companyId: string
name: string | null
}
}
const detachContactFromCompanyBase = {
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Intercom API access token',
},
contactId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the contact to detach from the company',
},
companyId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the company to detach the contact from',
},
},
request: {
url: (params: IntercomDetachContactFromCompanyParams) =>
buildIntercomUrl(`/contacts/${params.contactId}/companies/${params.companyId}`),
method: 'DELETE',
headers: (params: IntercomDetachContactFromCompanyParams) => ({
Authorization: `Bearer ${params.accessToken}`,
Accept: 'application/json',
'Content-Type': 'application/json',
'Intercom-Version': '2.14',
}),
},
} satisfies Pick<ToolConfig<IntercomDetachContactFromCompanyParams, any>, 'params' | 'request'>
export const intercomDetachContactFromCompanyV2Tool: ToolConfig<
IntercomDetachContactFromCompanyParams,
IntercomDetachContactFromCompanyV2Response
> = {
...detachContactFromCompanyBase,
id: 'intercom_detach_contact_from_company_v2',
name: 'Detach Contact from Company in Intercom',
description: 'Remove a contact from a company in Intercom',
version: '2.0.0',
transformResponse: async (response: Response) => {
if (!response.ok) {
const data = await response.json()
handleIntercomError(data, response.status, 'detach_contact_from_company')
}
const data = await response.json()
return {
success: true,
output: {
company: {
id: data.id,
type: data.type ?? 'company',
company_id: data.company_id ?? null,
name: data.name ?? null,
},
companyId: data.id,
name: data.name ?? null,
},
}
},
outputs: {
company: {
type: 'object',
description: 'The company object the contact was detached from',
properties: {
id: { type: 'string', description: 'Unique identifier for the company' },
type: { type: 'string', description: 'Object type (company)' },
company_id: { type: 'string', description: 'The company_id you defined' },
name: { type: 'string', description: 'Name of the company' },
},
},
companyId: { type: 'string', description: 'ID of the company' },
name: { type: 'string', description: 'Name of the company', optional: true },
},
}

View File

@@ -1,6 +1,6 @@
import { createLogger } from '@sim/logger'
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
import { buildIntercomUrl, handleIntercomError } from './types'
const logger = createLogger('IntercomGetCompany')
@@ -25,7 +25,7 @@ const getCompanyBase = {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
visibility: 'user-only',
description: 'Intercom API access token',
},
companyId: {

View File

@@ -1,5 +1,5 @@
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
import { buildIntercomUrl, handleIntercomError } from './types'
export interface IntercomGetContactParams {
accessToken: string
@@ -22,7 +22,7 @@ const intercomGetContactBase = {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
visibility: 'user-only',
description: 'Intercom API access token',
},
contactId: {

View File

@@ -1,6 +1,6 @@
import { createLogger } from '@sim/logger'
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
import { buildIntercomUrl, handleIntercomError } from './types'
const logger = createLogger('IntercomGetConversation')
@@ -27,7 +27,7 @@ const getConversationBase = {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
visibility: 'user-only',
description: 'Intercom API access token',
},
conversationId: {

View File

@@ -1,5 +1,5 @@
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
import { buildIntercomUrl, handleIntercomError } from './types'
export interface IntercomGetTicketParams {
accessToken: string
@@ -31,7 +31,7 @@ const getTicketBase = {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
visibility: 'user-only',
description: 'Intercom API access token',
},
ticketId: {

View File

@@ -1,24 +1,28 @@
// Contact tools
// Company tools
export { intercomAssignConversationV2Tool } from './assign_conversation'
export { intercomAttachContactToCompanyV2Tool } from './attach_contact_to_company'
export { intercomCloseConversationV2Tool } from './close_conversation'
export { intercomCreateCompanyTool, intercomCreateCompanyV2Tool } from './create_company'
export { intercomCreateContactTool, intercomCreateContactV2Tool } from './create_contact'
// Message tools
export { intercomCreateEventV2Tool } from './create_event'
export { intercomCreateMessageTool, intercomCreateMessageV2Tool } from './create_message'
// Ticket tools
export { intercomCreateNoteV2Tool } from './create_note'
export { intercomCreateTagV2Tool } from './create_tag'
export { intercomCreateTicketTool, intercomCreateTicketV2Tool } from './create_ticket'
export { intercomDeleteContactTool, intercomDeleteContactV2Tool } from './delete_contact'
export { intercomDetachContactFromCompanyV2Tool } from './detach_contact_from_company'
export { intercomGetCompanyTool, intercomGetCompanyV2Tool } from './get_company'
export { intercomGetContactTool, intercomGetContactV2Tool } from './get_contact'
// Conversation tools
export { intercomGetConversationTool, intercomGetConversationV2Tool } from './get_conversation'
export { intercomGetTicketTool, intercomGetTicketV2Tool } from './get_ticket'
export { intercomListAdminsV2Tool } from './list_admins'
export { intercomListCompaniesTool, intercomListCompaniesV2Tool } from './list_companies'
export { intercomListContactsTool, intercomListContactsV2Tool } from './list_contacts'
export {
intercomListConversationsTool,
intercomListConversationsV2Tool,
} from './list_conversations'
export { intercomListTagsV2Tool } from './list_tags'
export { intercomOpenConversationV2Tool } from './open_conversation'
export {
intercomReplyConversationTool,
intercomReplyConversationV2Tool,
@@ -28,4 +32,9 @@ export {
intercomSearchConversationsTool,
intercomSearchConversationsV2Tool,
} from './search_conversations'
export { intercomSnoozeConversationV2Tool } from './snooze_conversation'
export { intercomTagContactV2Tool } from './tag_contact'
export { intercomTagConversationV2Tool } from './tag_conversation'
export { intercomUntagContactV2Tool } from './untag_contact'
export { intercomUpdateContactTool, intercomUpdateContactV2Tool } from './update_contact'
export { intercomUpdateTicketV2Tool } from './update_ticket'

View File

@@ -0,0 +1,125 @@
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
export interface IntercomListAdminsParams {
accessToken: string
}
interface IntercomAdmin {
type: string
id: string
name: string
email: string
job_title: string | null
away_mode_enabled: boolean
away_mode_reassign: boolean
has_inbox_seat: boolean
team_ids: number[]
avatar: {
type: string
image_url: string | null
} | null
email_verified: boolean | null
}
export interface IntercomListAdminsV2Response {
success: boolean
output: {
admins: IntercomAdmin[]
type: string
}
}
const listAdminsBase = {
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Intercom API access token',
},
},
request: {
url: () => buildIntercomUrl('/admins'),
method: 'GET',
headers: (params: IntercomListAdminsParams) => ({
Authorization: `Bearer ${params.accessToken}`,
Accept: 'application/json',
'Content-Type': 'application/json',
'Intercom-Version': '2.14',
}),
},
} satisfies Pick<ToolConfig<IntercomListAdminsParams, any>, 'params' | 'request'>
export const intercomListAdminsV2Tool: ToolConfig<
IntercomListAdminsParams,
IntercomListAdminsV2Response
> = {
...listAdminsBase,
id: 'intercom_list_admins_v2',
name: 'List Admins from Intercom',
description: 'Fetch a list of all admins for the workspace',
version: '2.0.0',
transformResponse: async (response: Response) => {
if (!response.ok) {
const data = await response.json()
handleIntercomError(data, response.status, 'list_admins')
}
const data = await response.json()
return {
success: true,
output: {
admins: data.admins ?? [],
type: data.type ?? 'admin.list',
},
}
},
outputs: {
admins: {
type: 'array',
description: 'Array of admin objects',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Unique identifier for the admin' },
type: { type: 'string', description: 'Object type (admin)' },
name: { type: 'string', description: 'Name of the admin' },
email: { type: 'string', description: 'Email of the admin' },
job_title: { type: 'string', description: 'Job title of the admin', optional: true },
away_mode_enabled: {
type: 'boolean',
description: 'Whether admin is in away mode',
},
away_mode_reassign: {
type: 'boolean',
description: 'Whether to reassign conversations when away',
},
has_inbox_seat: {
type: 'boolean',
description: 'Whether admin has a paid inbox seat',
},
team_ids: {
type: 'array',
description: 'List of team IDs the admin belongs to',
},
avatar: {
type: 'object',
description: 'Avatar information',
optional: true,
},
email_verified: {
type: 'boolean',
description: 'Whether email is verified',
optional: true,
},
},
},
},
type: { type: 'string', description: 'Object type (admin.list)' },
},
}

View File

@@ -1,6 +1,6 @@
import { createLogger } from '@sim/logger'
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
import { buildIntercomUrl, handleIntercomError } from './types'
const logger = createLogger('IntercomListCompanies')
@@ -29,7 +29,7 @@ const listCompaniesBase = {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
visibility: 'user-only',
description: 'Intercom API access token',
},
per_page: {

View File

@@ -1,6 +1,6 @@
import { createLogger } from '@sim/logger'
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
import { buildIntercomUrl, handleIntercomError } from './types'
const logger = createLogger('IntercomListContacts')
@@ -28,7 +28,7 @@ const listContactsBase = {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
visibility: 'user-only',
description: 'Intercom API access token',
},
per_page: {

View File

@@ -1,6 +1,6 @@
import { createLogger } from '@sim/logger'
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
import { buildIntercomUrl, handleIntercomError } from './types'
const logger = createLogger('IntercomListConversations')
@@ -30,7 +30,7 @@ const listConversationsBase = {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
visibility: 'user-only',
description: 'Intercom API access token',
},
per_page: {

View File

@@ -0,0 +1,86 @@
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
export interface IntercomListTagsParams {
accessToken: string
}
interface IntercomTag {
type: string
id: string
name: string
}
export interface IntercomListTagsV2Response {
success: boolean
output: {
tags: IntercomTag[]
type: string
}
}
const listTagsBase = {
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Intercom API access token',
},
},
request: {
url: () => buildIntercomUrl('/tags'),
method: 'GET',
headers: (params: IntercomListTagsParams) => ({
Authorization: `Bearer ${params.accessToken}`,
Accept: 'application/json',
'Content-Type': 'application/json',
'Intercom-Version': '2.14',
}),
},
} satisfies Pick<ToolConfig<IntercomListTagsParams, any>, 'params' | 'request'>
export const intercomListTagsV2Tool: ToolConfig<
IntercomListTagsParams,
IntercomListTagsV2Response
> = {
...listTagsBase,
id: 'intercom_list_tags_v2',
name: 'List Tags from Intercom',
description: 'Fetch a list of all tags in the workspace',
version: '2.0.0',
transformResponse: async (response: Response) => {
if (!response.ok) {
const data = await response.json()
handleIntercomError(data, response.status, 'list_tags')
}
const data = await response.json()
return {
success: true,
output: {
tags: data.tags ?? [],
type: data.type ?? 'tag.list',
},
}
},
outputs: {
tags: {
type: 'array',
description: 'Array of tag objects',
items: {
type: 'object',
properties: {
id: { type: 'string', description: 'Unique identifier for the tag' },
type: { type: 'string', description: 'Object type (tag)' },
name: { type: 'string', description: 'Name of the tag' },
},
},
},
type: { type: 'string', description: 'Object type (list)' },
},
}

View File

@@ -0,0 +1,114 @@
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
export interface IntercomOpenConversationParams {
accessToken: string
conversationId: string
admin_id: string
}
export interface IntercomOpenConversationV2Response {
success: boolean
output: {
conversation: any
conversationId: string
state: string
}
}
const openConversationBase = {
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Intercom API access token',
},
conversationId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the conversation to open',
},
admin_id: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the admin performing the action',
},
},
request: {
url: (params: IntercomOpenConversationParams) =>
buildIntercomUrl(`/conversations/${params.conversationId}/parts`),
method: 'POST',
headers: (params: IntercomOpenConversationParams) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'Intercom-Version': '2.14',
}),
body: (params: IntercomOpenConversationParams) => ({
message_type: 'open',
type: 'admin',
admin_id: params.admin_id,
}),
},
} satisfies Pick<ToolConfig<IntercomOpenConversationParams, any>, 'params' | 'request'>
export const intercomOpenConversationV2Tool: ToolConfig<
IntercomOpenConversationParams,
IntercomOpenConversationV2Response
> = {
...openConversationBase,
id: 'intercom_open_conversation_v2',
name: 'Open Conversation in Intercom',
description: 'Open a closed or snoozed conversation in Intercom',
version: '2.0.0',
transformResponse: async (response: Response) => {
if (!response.ok) {
const data = await response.json()
handleIntercomError(data, response.status, 'open_conversation')
}
const data = await response.json()
return {
success: true,
output: {
conversation: {
id: data.id,
type: data.type ?? 'conversation',
state: data.state ?? 'open',
open: data.open ?? true,
read: data.read ?? false,
created_at: data.created_at ?? null,
updated_at: data.updated_at ?? null,
},
conversationId: data.id,
state: data.state ?? 'open',
},
}
},
outputs: {
conversation: {
type: 'object',
description: 'The opened conversation object',
properties: {
id: { type: 'string', description: 'Unique identifier for the conversation' },
type: { type: 'string', description: 'Object type (conversation)' },
state: { type: 'string', description: 'State of the conversation (open)' },
open: { type: 'boolean', description: 'Whether the conversation is open (true)' },
read: { type: 'boolean', description: 'Whether the conversation has been read' },
created_at: { type: 'number', description: 'Unix timestamp when conversation was created' },
updated_at: {
type: 'number',
description: 'Unix timestamp when conversation was last updated',
},
},
},
conversationId: { type: 'string', description: 'ID of the opened conversation' },
state: { type: 'string', description: 'State of the conversation (open)' },
},
}

View File

@@ -1,6 +1,6 @@
import { createLogger } from '@sim/logger'
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
import { buildIntercomUrl, handleIntercomError } from './types'
const logger = createLogger('IntercomReplyConversation')
@@ -31,7 +31,7 @@ const replyConversationBase = {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
visibility: 'user-only',
description: 'Intercom API access token',
},
conversationId: {

View File

@@ -1,6 +1,6 @@
import { createLogger } from '@sim/logger'
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
import { buildIntercomUrl, handleIntercomError } from './types'
const logger = createLogger('IntercomSearchContacts')
@@ -87,7 +87,7 @@ const searchContactsBase = {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
visibility: 'user-only',
description: 'Intercom API access token',
},
query: {

View File

@@ -1,6 +1,6 @@
import { createLogger } from '@sim/logger'
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
import { buildIntercomUrl, handleIntercomError } from './types'
const logger = createLogger('IntercomSearchConversations')
@@ -41,7 +41,7 @@ const searchConversationsBase = {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
visibility: 'user-only',
description: 'Intercom API access token',
},
query: {

View File

@@ -0,0 +1,124 @@
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
export interface IntercomSnoozeConversationParams {
accessToken: string
conversationId: string
admin_id: string
snoozed_until: number
}
export interface IntercomSnoozeConversationV2Response {
success: boolean
output: {
conversation: any
conversationId: string
state: string
snoozed_until: number | null
}
}
const snoozeConversationBase = {
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Intercom API access token',
},
conversationId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the conversation to snooze',
},
admin_id: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the admin performing the action',
},
snoozed_until: {
type: 'number',
required: true,
visibility: 'user-or-llm',
description: 'Unix timestamp for when the conversation should reopen',
},
},
request: {
url: (params: IntercomSnoozeConversationParams) =>
buildIntercomUrl(`/conversations/${params.conversationId}/reply`),
method: 'POST',
headers: (params: IntercomSnoozeConversationParams) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'Intercom-Version': '2.14',
}),
body: (params: IntercomSnoozeConversationParams) => ({
message_type: 'snoozed',
admin_id: params.admin_id,
snoozed_until: params.snoozed_until,
}),
},
} satisfies Pick<ToolConfig<IntercomSnoozeConversationParams, any>, 'params' | 'request'>
export const intercomSnoozeConversationV2Tool: ToolConfig<
IntercomSnoozeConversationParams,
IntercomSnoozeConversationV2Response
> = {
...snoozeConversationBase,
id: 'intercom_snooze_conversation_v2',
name: 'Snooze Conversation in Intercom',
description: 'Snooze a conversation to reopen at a future time',
version: '2.0.0',
transformResponse: async (response: Response) => {
if (!response.ok) {
const data = await response.json()
handleIntercomError(data, response.status, 'snooze_conversation')
}
const data = await response.json()
return {
success: true,
output: {
conversation: data,
conversationId: data.id,
state: data.state ?? 'snoozed',
snoozed_until: data.snoozed_until ?? null,
},
}
},
outputs: {
conversation: {
type: 'object',
description: 'The snoozed conversation object',
properties: {
id: { type: 'string', description: 'Unique identifier for the conversation' },
type: { type: 'string', description: 'Object type (conversation)' },
state: { type: 'string', description: 'State of the conversation (snoozed)' },
open: { type: 'boolean', description: 'Whether the conversation is open' },
snoozed_until: {
type: 'number',
description: 'Unix timestamp when conversation will reopen',
optional: true,
},
created_at: { type: 'number', description: 'Unix timestamp when conversation was created' },
updated_at: {
type: 'number',
description: 'Unix timestamp when conversation was last updated',
},
},
},
conversationId: { type: 'string', description: 'ID of the snoozed conversation' },
state: { type: 'string', description: 'State of the conversation (snoozed)' },
snoozed_until: {
type: 'number',
description: 'Unix timestamp when conversation will reopen',
optional: true,
},
},
}

View File

@@ -0,0 +1,89 @@
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
export interface IntercomTagContactParams {
accessToken: string
contactId: string
tagId: string
}
export interface IntercomTagContactV2Response {
success: boolean
output: {
id: string
name: string
type: string
}
}
const tagContactBase = {
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Intercom API access token',
},
contactId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the contact to tag',
},
tagId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the tag to apply',
},
},
request: {
url: (params: IntercomTagContactParams) =>
buildIntercomUrl(`/contacts/${params.contactId}/tags`),
method: 'POST',
headers: (params: IntercomTagContactParams) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'Intercom-Version': '2.14',
}),
body: (params: IntercomTagContactParams) => ({
id: params.tagId,
}),
},
} satisfies Pick<ToolConfig<IntercomTagContactParams, any>, 'params' | 'request'>
export const intercomTagContactV2Tool: ToolConfig<
IntercomTagContactParams,
IntercomTagContactV2Response
> = {
...tagContactBase,
id: 'intercom_tag_contact_v2',
name: 'Tag Contact in Intercom',
description: 'Add a tag to a specific contact',
version: '2.0.0',
transformResponse: async (response: Response) => {
if (!response.ok) {
const data = await response.json()
handleIntercomError(data, response.status, 'tag_contact')
}
const data = await response.json()
return {
success: true,
output: {
id: data.id,
name: data.name,
type: data.type ?? 'tag',
},
}
},
outputs: {
id: { type: 'string', description: 'Unique identifier for the tag' },
name: { type: 'string', description: 'Name of the tag' },
type: { type: 'string', description: 'Object type (tag)' },
},
}

View File

@@ -0,0 +1,97 @@
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
export interface IntercomTagConversationParams {
accessToken: string
conversationId: string
tagId: string
admin_id: string
}
export interface IntercomTagConversationV2Response {
success: boolean
output: {
id: string
name: string
type: string
}
}
const tagConversationBase = {
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Intercom API access token',
},
conversationId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the conversation to tag',
},
tagId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the tag to apply',
},
admin_id: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the admin applying the tag',
},
},
request: {
url: (params: IntercomTagConversationParams) =>
buildIntercomUrl(`/conversations/${params.conversationId}/tags`),
method: 'POST',
headers: (params: IntercomTagConversationParams) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'Intercom-Version': '2.14',
}),
body: (params: IntercomTagConversationParams) => ({
id: params.tagId,
admin_id: params.admin_id,
}),
},
} satisfies Pick<ToolConfig<IntercomTagConversationParams, any>, 'params' | 'request'>
export const intercomTagConversationV2Tool: ToolConfig<
IntercomTagConversationParams,
IntercomTagConversationV2Response
> = {
...tagConversationBase,
id: 'intercom_tag_conversation_v2',
name: 'Tag Conversation in Intercom',
description: 'Add a tag to a specific conversation',
version: '2.0.0',
transformResponse: async (response: Response) => {
if (!response.ok) {
const data = await response.json()
handleIntercomError(data, response.status, 'tag_conversation')
}
const data = await response.json()
return {
success: true,
output: {
id: data.id,
name: data.name,
type: data.type ?? 'tag',
},
}
},
outputs: {
id: { type: 'string', description: 'Unique identifier for the tag' },
name: { type: 'string', description: 'Name of the tag' },
type: { type: 'string', description: 'Object type (tag)' },
},
}

View File

@@ -2,14 +2,13 @@ import { createLogger } from '@sim/logger'
const logger = createLogger('Intercom')
// Base params for Intercom API
export interface IntercomBaseParams {
accessToken: string // OAuth token or API token (hidden)
accessToken: string
}
export interface IntercomPaginationParams {
per_page?: number
starting_after?: string // Cursor for pagination
starting_after?: string
}
export interface IntercomPagingInfo {
@@ -33,12 +32,10 @@ export interface IntercomResponse<T> {
}
}
// Helper function to build Intercom API URLs
export function buildIntercomUrl(path: string): string {
return `https://api.intercom.io${path}`
}
// Helper function for consistent error handling
export function handleIntercomError(data: any, status: number, operation: string): never {
logger.error(`Intercom API request failed for ${operation}`, { data, status })

View File

@@ -0,0 +1,87 @@
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
export interface IntercomUntagContactParams {
accessToken: string
contactId: string
tagId: string
}
export interface IntercomUntagContactV2Response {
success: boolean
output: {
id: string
name: string
type: string
}
}
const untagContactBase = {
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Intercom API access token',
},
contactId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the contact to untag',
},
tagId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the tag to remove',
},
},
request: {
url: (params: IntercomUntagContactParams) =>
buildIntercomUrl(`/contacts/${params.contactId}/tags/${params.tagId}`),
method: 'DELETE',
headers: (params: IntercomUntagContactParams) => ({
Authorization: `Bearer ${params.accessToken}`,
Accept: 'application/json',
'Content-Type': 'application/json',
'Intercom-Version': '2.14',
}),
},
} satisfies Pick<ToolConfig<IntercomUntagContactParams, any>, 'params' | 'request'>
export const intercomUntagContactV2Tool: ToolConfig<
IntercomUntagContactParams,
IntercomUntagContactV2Response
> = {
...untagContactBase,
id: 'intercom_untag_contact_v2',
name: 'Untag Contact in Intercom',
description: 'Remove a tag from a specific contact',
version: '2.0.0',
transformResponse: async (response: Response) => {
if (!response.ok) {
const data = await response.json()
handleIntercomError(data, response.status, 'untag_contact')
}
const data = await response.json()
return {
success: true,
output: {
id: data.id,
name: data.name,
type: data.type ?? 'tag',
},
}
},
outputs: {
id: { type: 'string', description: 'Unique identifier for the tag that was removed' },
name: { type: 'string', description: 'Name of the tag that was removed' },
type: { type: 'string', description: 'Object type (tag)' },
},
}

View File

@@ -1,6 +1,6 @@
import { createLogger } from '@sim/logger'
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
import { buildIntercomUrl, handleIntercomError } from './types'
const logger = createLogger('IntercomUpdateContact')
@@ -38,7 +38,7 @@ const intercomUpdateContactBase = {
accessToken: {
type: 'string',
required: true,
visibility: 'hidden',
visibility: 'user-only',
description: 'Intercom API access token',
},
contactId: {

View File

@@ -0,0 +1,193 @@
import { createLogger } from '@sim/logger'
import { buildIntercomUrl, handleIntercomError } from '@/tools/intercom/types'
import type { ToolConfig } from '@/tools/types'
const logger = createLogger('IntercomUpdateTicket')
export interface IntercomUpdateTicketParams {
accessToken: string
ticketId: string
ticket_attributes?: string
open?: boolean
is_shared?: boolean
snoozed_until?: number
admin_id?: string
assignee_id?: string
}
export interface IntercomUpdateTicketV2Response {
success: boolean
output: {
ticket: any
ticketId: string
ticket_state: string
}
}
const updateTicketBase = {
params: {
accessToken: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Intercom API access token',
},
ticketId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The ID of the ticket to update',
},
ticket_attributes: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'JSON object with ticket attributes (e.g., {"_default_title_":"New Title","_default_description_":"Updated description"})',
},
open: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Set to false to close the ticket, true to keep it open',
},
is_shared: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Whether the ticket is visible to users',
},
snoozed_until: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Unix timestamp for when the ticket should reopen',
},
admin_id: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description:
'The ID of the admin performing the update (needed for workflows and attribution)',
},
assignee_id: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'The ID of the admin or team to assign the ticket to. Set to "0" to unassign.',
},
},
request: {
url: (params: IntercomUpdateTicketParams) => buildIntercomUrl(`/tickets/${params.ticketId}`),
method: 'PUT',
headers: (params: IntercomUpdateTicketParams) => ({
Authorization: `Bearer ${params.accessToken}`,
'Content-Type': 'application/json',
'Intercom-Version': '2.14',
}),
body: (params: IntercomUpdateTicketParams) => {
const payload: any = {}
if (params.ticket_attributes) {
try {
payload.ticket_attributes = JSON.parse(params.ticket_attributes)
} catch (error) {
logger.error('Failed to parse ticket_attributes', { error })
throw new Error('ticket_attributes must be a valid JSON object')
}
}
if (params.open !== undefined) {
payload.open = params.open
}
if (params.is_shared !== undefined) {
payload.is_shared = params.is_shared
}
if (params.snoozed_until !== undefined) {
payload.snoozed_until = params.snoozed_until
}
if (params.admin_id) {
payload.admin_id = params.admin_id
}
if (params.assignee_id) {
payload.assignee_id = params.assignee_id
}
return payload
},
},
} satisfies Pick<ToolConfig<IntercomUpdateTicketParams, any>, 'params' | 'request'>
export const intercomUpdateTicketV2Tool: ToolConfig<
IntercomUpdateTicketParams,
IntercomUpdateTicketV2Response
> = {
...updateTicketBase,
id: 'intercom_update_ticket_v2',
name: 'Update Ticket in Intercom',
description: 'Update a ticket in Intercom (change state, assignment, attributes)',
version: '2.0.0',
transformResponse: async (response: Response) => {
if (!response.ok) {
const data = await response.json()
handleIntercomError(data, response.status, 'update_ticket')
}
const data = await response.json()
return {
success: true,
output: {
ticket: {
id: data.id,
type: data.type ?? 'ticket',
ticket_id: data.ticket_id ?? null,
ticket_state: data.ticket_state ?? null,
ticket_attributes: data.ticket_attributes ?? null,
open: data.open ?? null,
is_shared: data.is_shared ?? null,
snoozed_until: data.snoozed_until ?? null,
admin_assignee_id: data.admin_assignee_id ?? null,
team_assignee_id: data.team_assignee_id ?? null,
created_at: data.created_at ?? null,
updated_at: data.updated_at ?? null,
},
ticketId: data.id,
ticket_state: data.ticket_state ?? null,
},
}
},
outputs: {
ticket: {
type: 'object',
description: 'The updated ticket object',
properties: {
id: { type: 'string', description: 'Unique identifier for the ticket' },
type: { type: 'string', description: 'Object type (ticket)' },
ticket_id: { type: 'string', description: 'Ticket ID shown in Intercom UI' },
ticket_state: { type: 'string', description: 'State of the ticket' },
ticket_attributes: { type: 'object', description: 'Attributes of the ticket' },
open: { type: 'boolean', description: 'Whether the ticket is open' },
is_shared: { type: 'boolean', description: 'Whether the ticket is visible to users' },
snoozed_until: {
type: 'number',
description: 'Unix timestamp when ticket will reopen',
optional: true,
},
admin_assignee_id: { type: 'string', description: 'ID of assigned admin', optional: true },
team_assignee_id: { type: 'string', description: 'ID of assigned team', optional: true },
created_at: { type: 'number', description: 'Unix timestamp when ticket was created' },
updated_at: { type: 'number', description: 'Unix timestamp when ticket was last updated' },
},
},
ticketId: { type: 'string', description: 'ID of the updated ticket' },
ticket_state: { type: 'string', description: 'Current state of the ticket' },
},
}

View File

@@ -1,6 +1,6 @@
import type { PolymarketActivity } from '@/tools/polymarket/types'
import { buildDataUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import type { PolymarketActivity } from './types'
import { buildDataUrl, handlePolymarketError } from './types'
export interface PolymarketGetActivityParams {
user: string

View File

@@ -1,6 +1,6 @@
import type { PolymarketEvent } from '@/tools/polymarket/types'
import { buildGammaUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import type { PolymarketEvent } from './types'
import { buildGammaUrl, handlePolymarketError } from './types'
export interface PolymarketGetEventParams {
eventId?: string // Event ID

View File

@@ -1,6 +1,6 @@
import type { PolymarketEvent, PolymarketPaginationParams } from '@/tools/polymarket/types'
import { buildGammaUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import type { PolymarketEvent, PolymarketPaginationParams } from './types'
import { buildGammaUrl, handlePolymarketError } from './types'
export interface PolymarketGetEventsParams extends PolymarketPaginationParams {
closed?: string

View File

@@ -1,6 +1,6 @@
import type { PolymarketMarketHolders } from '@/tools/polymarket/types'
import { buildDataUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import type { PolymarketMarketHolders } from './types'
import { buildDataUrl, handlePolymarketError } from './types'
export interface PolymarketGetHoldersParams {
market: string

View File

@@ -1,5 +1,5 @@
import { buildClobUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import { buildClobUrl, handlePolymarketError } from './types'
export interface PolymarketGetLastTradePriceParams {
tokenId: string // The token ID (CLOB token ID from market)

View File

@@ -1,6 +1,6 @@
import type { PolymarketLeaderboardEntry } from '@/tools/polymarket/types'
import { buildDataUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import type { PolymarketLeaderboardEntry } from './types'
import { buildDataUrl, handlePolymarketError } from './types'
export interface PolymarketGetLeaderboardParams {
category?: string

View File

@@ -1,6 +1,6 @@
import type { PolymarketMarket } from '@/tools/polymarket/types'
import { buildGammaUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import type { PolymarketMarket } from './types'
import { buildGammaUrl, handlePolymarketError } from './types'
export interface PolymarketGetMarketParams {
marketId?: string // Market ID

View File

@@ -1,6 +1,6 @@
import type { PolymarketMarket, PolymarketPaginationParams } from '@/tools/polymarket/types'
import { buildGammaUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import type { PolymarketMarket, PolymarketPaginationParams } from './types'
import { buildGammaUrl, handlePolymarketError } from './types'
export interface PolymarketGetMarketsParams extends PolymarketPaginationParams {
closed?: string

View File

@@ -1,5 +1,5 @@
import { buildClobUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import { buildClobUrl, handlePolymarketError } from './types'
export interface PolymarketGetMidpointParams {
tokenId: string // The token ID (CLOB token ID from market)

View File

@@ -1,6 +1,6 @@
import type { PolymarketOrderBook } from '@/tools/polymarket/types'
import { buildClobUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import type { PolymarketOrderBook } from './types'
import { buildClobUrl, handlePolymarketError } from './types'
export interface PolymarketGetOrderbookParams {
tokenId: string // The token ID (CLOB token ID from market)

View File

@@ -1,6 +1,6 @@
import type { PolymarketPosition } from '@/tools/polymarket/types'
import { buildDataUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import type { PolymarketPosition } from './types'
import { buildDataUrl, handlePolymarketError } from './types'
export interface PolymarketGetPositionsParams {
user: string

View File

@@ -1,5 +1,5 @@
import { buildClobUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import { buildClobUrl, handlePolymarketError } from './types'
export interface PolymarketGetPriceParams {
tokenId: string // The token ID (CLOB token ID from market)

View File

@@ -1,6 +1,6 @@
import type { PolymarketPriceHistoryEntry } from '@/tools/polymarket/types'
import { buildClobUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import type { PolymarketPriceHistoryEntry } from './types'
import { buildClobUrl, handlePolymarketError } from './types'
export interface PolymarketGetPriceHistoryParams {
tokenId: string

View File

@@ -1,6 +1,6 @@
import type { PolymarketPaginationParams, PolymarketSeries } from '@/tools/polymarket/types'
import { buildGammaUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import type { PolymarketPaginationParams, PolymarketSeries } from './types'
import { buildGammaUrl, handlePolymarketError } from './types'
export interface PolymarketGetSeriesParams extends PolymarketPaginationParams {}

View File

@@ -1,6 +1,6 @@
import type { PolymarketSeries } from '@/tools/polymarket/types'
import { buildGammaUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import type { PolymarketSeries } from './types'
import { buildGammaUrl, handlePolymarketError } from './types'
export interface PolymarketGetSeriesByIdParams {
seriesId: string // Series ID (required)

View File

@@ -1,6 +1,6 @@
import type { PolymarketSpread } from '@/tools/polymarket/types'
import { buildClobUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import type { PolymarketSpread } from './types'
import { buildClobUrl, handlePolymarketError } from './types'
export interface PolymarketGetSpreadParams {
tokenId: string // The token ID (CLOB token ID from market)

View File

@@ -1,6 +1,6 @@
import type { PolymarketPaginationParams, PolymarketTag } from '@/tools/polymarket/types'
import { buildGammaUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import type { PolymarketPaginationParams, PolymarketTag } from './types'
import { buildGammaUrl, handlePolymarketError } from './types'
export interface PolymarketGetTagsParams extends PolymarketPaginationParams {}

View File

@@ -1,5 +1,5 @@
import { buildClobUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import { buildClobUrl, handlePolymarketError } from './types'
export interface PolymarketGetTickSizeParams {
tokenId: string // The token ID (CLOB token ID from market)

View File

@@ -1,6 +1,6 @@
import type { PolymarketTrade } from '@/tools/polymarket/types'
import { buildDataUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import type { PolymarketTrade } from './types'
import { buildDataUrl, handlePolymarketError } from './types'
export interface PolymarketGetTradesParams {
user?: string

View File

@@ -1,21 +1,20 @@
export * from './get_activity'
export * from './get_event'
export * from './get_events'
export * from './get_holders'
export * from './get_last_trade_price'
export * from './get_leaderboard'
export * from './get_market'
export * from './get_markets'
export * from './get_midpoint'
export * from './get_orderbook'
export * from './get_positions'
export * from './get_price'
export * from './get_price_history'
export * from './get_series'
export * from './get_series_by_id'
export * from './get_spread'
export * from './get_tags'
export * from './get_tick_size'
export * from './get_trades'
export * from './search'
export * from './types'
export { polymarketGetActivityTool } from './get_activity'
export { polymarketGetEventTool } from './get_event'
export { polymarketGetEventsTool } from './get_events'
export { polymarketGetHoldersTool } from './get_holders'
export { polymarketGetLastTradePriceTool } from './get_last_trade_price'
export { polymarketGetLeaderboardTool } from './get_leaderboard'
export { polymarketGetMarketTool } from './get_market'
export { polymarketGetMarketsTool } from './get_markets'
export { polymarketGetMidpointTool } from './get_midpoint'
export { polymarketGetOrderbookTool } from './get_orderbook'
export { polymarketGetPositionsTool } from './get_positions'
export { polymarketGetPriceTool } from './get_price'
export { polymarketGetPriceHistoryTool } from './get_price_history'
export { polymarketGetSeriesTool } from './get_series'
export { polymarketGetSeriesByIdTool } from './get_series_by_id'
export { polymarketGetSpreadTool } from './get_spread'
export { polymarketGetTagsTool } from './get_tags'
export { polymarketGetTickSizeTool } from './get_tick_size'
export { polymarketGetTradesTool } from './get_trades'
export { polymarketSearchTool } from './search'

View File

@@ -1,6 +1,6 @@
import type { PolymarketSearchResult } from '@/tools/polymarket/types'
import { buildGammaUrl, handlePolymarketError } from '@/tools/polymarket/types'
import type { ToolConfig } from '@/tools/types'
import type { PolymarketSearchResult } from './types'
import { buildGammaUrl, handlePolymarketError } from './types'
export interface PolymarketSearchParams {
query: string

View File

@@ -663,16 +663,23 @@ import {
incidentioWorkflowsUpdateTool,
} from '@/tools/incidentio'
import {
intercomAssignConversationV2Tool,
intercomAttachContactToCompanyV2Tool,
intercomCloseConversationV2Tool,
intercomCreateCompanyTool,
intercomCreateCompanyV2Tool,
intercomCreateContactTool,
intercomCreateContactV2Tool,
intercomCreateEventV2Tool,
intercomCreateMessageTool,
intercomCreateMessageV2Tool,
intercomCreateNoteV2Tool,
intercomCreateTagV2Tool,
intercomCreateTicketTool,
intercomCreateTicketV2Tool,
intercomDeleteContactTool,
intercomDeleteContactV2Tool,
intercomDetachContactFromCompanyV2Tool,
intercomGetCompanyTool,
intercomGetCompanyV2Tool,
intercomGetContactTool,
@@ -681,20 +688,28 @@ import {
intercomGetConversationV2Tool,
intercomGetTicketTool,
intercomGetTicketV2Tool,
intercomListAdminsV2Tool,
intercomListCompaniesTool,
intercomListCompaniesV2Tool,
intercomListContactsTool,
intercomListContactsV2Tool,
intercomListConversationsTool,
intercomListConversationsV2Tool,
intercomListTagsV2Tool,
intercomOpenConversationV2Tool,
intercomReplyConversationTool,
intercomReplyConversationV2Tool,
intercomSearchContactsTool,
intercomSearchContactsV2Tool,
intercomSearchConversationsTool,
intercomSearchConversationsV2Tool,
intercomSnoozeConversationV2Tool,
intercomTagContactV2Tool,
intercomTagConversationV2Tool,
intercomUntagContactV2Tool,
intercomUpdateContactTool,
intercomUpdateContactV2Tool,
intercomUpdateTicketV2Tool,
} from '@/tools/intercom'
import { jinaReadUrlTool, jinaSearchTool } from '@/tools/jina'
import {
@@ -3126,8 +3141,23 @@ export const tools: Record<string, ToolConfig> = {
intercom_create_ticket_v2: intercomCreateTicketV2Tool,
intercom_get_ticket: intercomGetTicketTool,
intercom_get_ticket_v2: intercomGetTicketV2Tool,
intercom_update_ticket_v2: intercomUpdateTicketV2Tool,
intercom_create_message: intercomCreateMessageTool,
intercom_create_message_v2: intercomCreateMessageV2Tool,
intercom_list_admins_v2: intercomListAdminsV2Tool,
intercom_close_conversation_v2: intercomCloseConversationV2Tool,
intercom_open_conversation_v2: intercomOpenConversationV2Tool,
intercom_snooze_conversation_v2: intercomSnoozeConversationV2Tool,
intercom_assign_conversation_v2: intercomAssignConversationV2Tool,
intercom_list_tags_v2: intercomListTagsV2Tool,
intercom_create_tag_v2: intercomCreateTagV2Tool,
intercom_tag_contact_v2: intercomTagContactV2Tool,
intercom_untag_contact_v2: intercomUntagContactV2Tool,
intercom_tag_conversation_v2: intercomTagConversationV2Tool,
intercom_create_note_v2: intercomCreateNoteV2Tool,
intercom_create_event_v2: intercomCreateEventV2Tool,
intercom_attach_contact_to_company_v2: intercomAttachContactToCompanyV2Tool,
intercom_detach_contact_from_company_v2: intercomDetachContactFromCompanyV2Tool,
sentry_issues_list: listIssuesTool,
sentry_issues_get: getIssueTool,
sentry_issues_update: updateIssueTool,