mirror of
https://github.com/simstudioai/sim.git
synced 2026-01-27 07:48:22 -05:00
Compare commits
42 Commits
feat/termi
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab4e9dc72f | ||
|
|
46ba315701 | ||
|
|
077e702dd8 | ||
|
|
1c58c35bd8 | ||
|
|
d63a5cb504 | ||
|
|
8bd5d41723 | ||
|
|
c12931bc50 | ||
|
|
e9c4251c1c | ||
|
|
cc2be33d6b | ||
|
|
45371e521e | ||
|
|
0ce0f98aa5 | ||
|
|
dff1c9d083 | ||
|
|
b09f683072 | ||
|
|
a8bb0db660 | ||
|
|
af82820a28 | ||
|
|
4372841797 | ||
|
|
5e8c843241 | ||
|
|
7bf3d73ee6 | ||
|
|
7ffc11a738 | ||
|
|
be578e2ed7 | ||
|
|
f415e5edc4 | ||
|
|
13a6e6c3fa | ||
|
|
f5ab7f21ae | ||
|
|
bfb6fffe38 | ||
|
|
4fbec0a43f | ||
|
|
585f5e365b | ||
|
|
3792bdd252 | ||
|
|
eb5d1f3e5b | ||
|
|
54ab82c8dd | ||
|
|
f895bf469b | ||
|
|
dd3209af06 | ||
|
|
b6ba3b50a7 | ||
|
|
b304233062 | ||
|
|
57e4b49bd6 | ||
|
|
e12dd204ed | ||
|
|
3d9d9cbc54 | ||
|
|
0f4ec962ad | ||
|
|
4827866f9a | ||
|
|
3e697d9ed9 | ||
|
|
4431a1a484 | ||
|
|
4d1a9a3f22 | ||
|
|
eb07a080fb |
@@ -101,7 +101,6 @@ import {
|
||||
ShopifyIcon,
|
||||
SlackIcon,
|
||||
SmtpIcon,
|
||||
SpotifyIcon,
|
||||
SQSIcon,
|
||||
SshIcon,
|
||||
STTIcon,
|
||||
@@ -182,7 +181,7 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
|
||||
jina: JinaAIIcon,
|
||||
jira: JiraIcon,
|
||||
jira_service_management: JiraServiceManagementIcon,
|
||||
kalshi: KalshiIcon,
|
||||
kalshi_v2: KalshiIcon,
|
||||
knowledge: PackageSearchIcon,
|
||||
langsmith: LangsmithIcon,
|
||||
lemlist: LemlistIcon,
|
||||
@@ -229,7 +228,6 @@ export const blockTypeToIconMap: Record<string, IconComponent> = {
|
||||
shopify: ShopifyIcon,
|
||||
slack: SlackIcon,
|
||||
smtp: SmtpIcon,
|
||||
spotify: SpotifyIcon,
|
||||
sqs: SQSIcon,
|
||||
ssh: SshIcon,
|
||||
stagehand: StagehandIcon,
|
||||
|
||||
@@ -47,6 +47,7 @@ Runs a browser automation task using BrowserUse
|
||||
| `save_browser_data` | boolean | No | Whether to save browser data |
|
||||
| `model` | string | No | LLM model to use \(default: gpt-4o\) |
|
||||
| `apiKey` | string | Yes | API key for BrowserUse API |
|
||||
| `profile_id` | string | No | Browser profile ID for persistent sessions \(cookies, login state\) |
|
||||
|
||||
#### Output
|
||||
|
||||
|
||||
@@ -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 |
|
||||
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ description: Access prediction markets and trade on Kalshi
|
||||
import { BlockInfoCard } from "@/components/ui/block-info-card"
|
||||
|
||||
<BlockInfoCard
|
||||
type="kalshi"
|
||||
type="kalshi_v2"
|
||||
color="#09C285"
|
||||
/>
|
||||
|
||||
@@ -36,7 +36,7 @@ Integrate Kalshi prediction markets into the workflow. Can get markets, market,
|
||||
|
||||
### `kalshi_get_markets`
|
||||
|
||||
Retrieve a list of prediction markets from Kalshi with optional filtering
|
||||
Retrieve a list of prediction markets from Kalshi with all filtering options (V2 - full API response)
|
||||
|
||||
#### Input
|
||||
|
||||
@@ -52,12 +52,12 @@ Retrieve a list of prediction markets from Kalshi with optional filtering
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `markets` | array | Array of market objects |
|
||||
| `paging` | object | Pagination cursor for fetching more results |
|
||||
| `markets` | array | Array of market objects with all API fields |
|
||||
| `cursor` | string | Pagination cursor for fetching more results |
|
||||
|
||||
### `kalshi_get_market`
|
||||
|
||||
Retrieve details of a specific prediction market by ticker
|
||||
Retrieve details of a specific prediction market by ticker (V2 - full API response)
|
||||
|
||||
#### Input
|
||||
|
||||
@@ -69,11 +69,62 @@ Retrieve details of a specific prediction market by ticker
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `market` | object | Market object with details |
|
||||
| `market` | object | Market object with all API fields |
|
||||
| ↳ `ticker` | string | Market ticker |
|
||||
| ↳ `event_ticker` | string | Event ticker |
|
||||
| ↳ `market_type` | string | Market type |
|
||||
| ↳ `title` | string | Market title |
|
||||
| ↳ `subtitle` | string | Market subtitle |
|
||||
| ↳ `yes_sub_title` | string | Yes outcome subtitle |
|
||||
| ↳ `no_sub_title` | string | No outcome subtitle |
|
||||
| ↳ `open_time` | string | Market open time |
|
||||
| ↳ `close_time` | string | Market close time |
|
||||
| ↳ `expected_expiration_time` | string | Expected expiration time |
|
||||
| ↳ `expiration_time` | string | Expiration time |
|
||||
| ↳ `latest_expiration_time` | string | Latest expiration time |
|
||||
| ↳ `settlement_timer_seconds` | number | Settlement timer in seconds |
|
||||
| ↳ `status` | string | Market status |
|
||||
| ↳ `response_price_units` | string | Response price units |
|
||||
| ↳ `notional_value` | number | Notional value |
|
||||
| ↳ `tick_size` | number | Tick size |
|
||||
| ↳ `yes_bid` | number | Current yes bid price |
|
||||
| ↳ `yes_ask` | number | Current yes ask price |
|
||||
| ↳ `no_bid` | number | Current no bid price |
|
||||
| ↳ `no_ask` | number | Current no ask price |
|
||||
| ↳ `last_price` | number | Last trade price |
|
||||
| ↳ `previous_yes_bid` | number | Previous yes bid |
|
||||
| ↳ `previous_yes_ask` | number | Previous yes ask |
|
||||
| ↳ `previous_price` | number | Previous price |
|
||||
| ↳ `volume` | number | Total volume |
|
||||
| ↳ `volume_24h` | number | 24-hour volume |
|
||||
| ↳ `liquidity` | number | Market liquidity |
|
||||
| ↳ `open_interest` | number | Open interest |
|
||||
| ↳ `result` | string | Market result |
|
||||
| ↳ `cap_strike` | number | Cap strike |
|
||||
| ↳ `floor_strike` | number | Floor strike |
|
||||
| ↳ `can_close_early` | boolean | Can close early |
|
||||
| ↳ `expiration_value` | string | Expiration value |
|
||||
| ↳ `category` | string | Market category |
|
||||
| ↳ `risk_limit_cents` | number | Risk limit in cents |
|
||||
| ↳ `strike_type` | string | Strike type |
|
||||
| ↳ `rules_primary` | string | Primary rules |
|
||||
| ↳ `rules_secondary` | string | Secondary rules |
|
||||
| ↳ `settlement_source_url` | string | Settlement source URL |
|
||||
| ↳ `custom_strike` | object | Custom strike object |
|
||||
| ↳ `underlying` | string | Underlying asset |
|
||||
| ↳ `settlement_value` | number | Settlement value |
|
||||
| ↳ `cfd_contract_size` | number | CFD contract size |
|
||||
| ↳ `yes_fee_fp` | number | Yes fee \(fixed-point\) |
|
||||
| ↳ `no_fee_fp` | number | No fee \(fixed-point\) |
|
||||
| ↳ `last_price_fp` | number | Last price \(fixed-point\) |
|
||||
| ↳ `yes_bid_fp` | number | Yes bid \(fixed-point\) |
|
||||
| ↳ `yes_ask_fp` | number | Yes ask \(fixed-point\) |
|
||||
| ↳ `no_bid_fp` | number | No bid \(fixed-point\) |
|
||||
| ↳ `no_ask_fp` | number | No ask \(fixed-point\) |
|
||||
|
||||
### `kalshi_get_events`
|
||||
|
||||
Retrieve a list of events from Kalshi with optional filtering
|
||||
Retrieve a list of events from Kalshi with optional filtering (V2 - exact API response)
|
||||
|
||||
#### Input
|
||||
|
||||
@@ -90,11 +141,12 @@ Retrieve a list of events from Kalshi with optional filtering
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `events` | array | Array of event objects |
|
||||
| `paging` | object | Pagination cursor for fetching more results |
|
||||
| `milestones` | array | Array of milestone objects \(if requested\) |
|
||||
| `cursor` | string | Pagination cursor for fetching more results |
|
||||
|
||||
### `kalshi_get_event`
|
||||
|
||||
Retrieve details of a specific event by ticker
|
||||
Retrieve details of a specific event by ticker (V2 - exact API response)
|
||||
|
||||
#### Input
|
||||
|
||||
@@ -107,11 +159,23 @@ Retrieve details of a specific event by ticker
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `event` | object | Event object with details |
|
||||
| `event` | object | Event object with full details matching Kalshi API response |
|
||||
| ↳ `event_ticker` | string | Event ticker |
|
||||
| ↳ `series_ticker` | string | Series ticker |
|
||||
| ↳ `title` | string | Event title |
|
||||
| ↳ `sub_title` | string | Event subtitle |
|
||||
| ↳ `mutually_exclusive` | boolean | Mutually exclusive markets |
|
||||
| ↳ `category` | string | Event category |
|
||||
| ↳ `collateral_return_type` | string | Collateral return type |
|
||||
| ↳ `strike_date` | string | Strike date |
|
||||
| ↳ `strike_period` | string | Strike period |
|
||||
| ↳ `available_on_brokers` | boolean | Available on brokers |
|
||||
| ↳ `product_metadata` | object | Product metadata |
|
||||
| ↳ `markets` | array | Nested markets \(if requested\) |
|
||||
|
||||
### `kalshi_get_balance`
|
||||
|
||||
Retrieve your account balance and portfolio value from Kalshi
|
||||
Retrieve your account balance and portfolio value from Kalshi (V2 - exact API response)
|
||||
|
||||
#### Input
|
||||
|
||||
@@ -125,11 +189,12 @@ Retrieve your account balance and portfolio value from Kalshi
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `balance` | number | Account balance in cents |
|
||||
| `portfolioValue` | number | Portfolio value in cents |
|
||||
| `portfolio_value` | number | Portfolio value in cents |
|
||||
| `updated_ts` | number | Unix timestamp of last update \(milliseconds\) |
|
||||
|
||||
### `kalshi_get_positions`
|
||||
|
||||
Retrieve your open positions from Kalshi
|
||||
Retrieve your open positions from Kalshi (V2 - exact API response)
|
||||
|
||||
#### Input
|
||||
|
||||
@@ -147,12 +212,13 @@ Retrieve your open positions from Kalshi
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `positions` | array | Array of position objects |
|
||||
| `paging` | object | Pagination cursor for fetching more results |
|
||||
| `market_positions` | array | Array of market position objects |
|
||||
| `event_positions` | array | Array of event position objects |
|
||||
| `cursor` | string | Pagination cursor for fetching more results |
|
||||
|
||||
### `kalshi_get_orders`
|
||||
|
||||
Retrieve your orders from Kalshi with optional filtering
|
||||
Retrieve your orders from Kalshi with optional filtering (V2 with full API response)
|
||||
|
||||
#### Input
|
||||
|
||||
@@ -170,12 +236,12 @@ Retrieve your orders from Kalshi with optional filtering
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `orders` | array | Array of order objects |
|
||||
| `paging` | object | Pagination cursor for fetching more results |
|
||||
| `orders` | array | Array of order objects with full API response fields |
|
||||
| `cursor` | string | Pagination cursor for fetching more results |
|
||||
|
||||
### `kalshi_get_order`
|
||||
|
||||
Retrieve details of a specific order by ID from Kalshi
|
||||
Retrieve details of a specific order by ID from Kalshi (V2 with full API response)
|
||||
|
||||
#### Input
|
||||
|
||||
@@ -189,11 +255,44 @@ Retrieve details of a specific order by ID from Kalshi
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `order` | object | Order object with details |
|
||||
| `order` | object | Order object with full API response fields |
|
||||
| ↳ `order_id` | string | Order ID |
|
||||
| ↳ `user_id` | string | User ID |
|
||||
| ↳ `client_order_id` | string | Client order ID |
|
||||
| ↳ `ticker` | string | Market ticker |
|
||||
| ↳ `side` | string | Order side \(yes/no\) |
|
||||
| ↳ `action` | string | Action \(buy/sell\) |
|
||||
| ↳ `type` | string | Order type \(limit/market\) |
|
||||
| ↳ `status` | string | Order status \(resting/canceled/executed\) |
|
||||
| ↳ `yes_price` | number | Yes price in cents |
|
||||
| ↳ `no_price` | number | No price in cents |
|
||||
| ↳ `yes_price_dollars` | string | Yes price in dollars |
|
||||
| ↳ `no_price_dollars` | string | No price in dollars |
|
||||
| ↳ `fill_count` | number | Filled contract count |
|
||||
| ↳ `fill_count_fp` | string | Filled count \(fixed-point\) |
|
||||
| ↳ `remaining_count` | number | Remaining contracts |
|
||||
| ↳ `remaining_count_fp` | string | Remaining count \(fixed-point\) |
|
||||
| ↳ `initial_count` | number | Initial contract count |
|
||||
| ↳ `initial_count_fp` | string | Initial count \(fixed-point\) |
|
||||
| ↳ `taker_fees` | number | Taker fees in cents |
|
||||
| ↳ `maker_fees` | number | Maker fees in cents |
|
||||
| ↳ `taker_fees_dollars` | string | Taker fees in dollars |
|
||||
| ↳ `maker_fees_dollars` | string | Maker fees in dollars |
|
||||
| ↳ `taker_fill_cost` | number | Taker fill cost in cents |
|
||||
| ↳ `maker_fill_cost` | number | Maker fill cost in cents |
|
||||
| ↳ `taker_fill_cost_dollars` | string | Taker fill cost in dollars |
|
||||
| ↳ `maker_fill_cost_dollars` | string | Maker fill cost in dollars |
|
||||
| ↳ `queue_position` | number | Queue position \(deprecated\) |
|
||||
| ↳ `expiration_time` | string | Order expiration time |
|
||||
| ↳ `created_time` | string | Order creation time |
|
||||
| ↳ `last_update_time` | string | Last update time |
|
||||
| ↳ `self_trade_prevention_type` | string | Self-trade prevention type |
|
||||
| ↳ `order_group_id` | string | Order group ID |
|
||||
| ↳ `cancel_order_on_pause` | boolean | Cancel on market pause |
|
||||
|
||||
### `kalshi_get_orderbook`
|
||||
|
||||
Retrieve the orderbook (yes and no bids) for a specific market
|
||||
Retrieve the orderbook (yes and no bids) for a specific market (V2 - includes depth and fp fields)
|
||||
|
||||
#### Input
|
||||
|
||||
@@ -205,11 +304,18 @@ Retrieve the orderbook (yes and no bids) for a specific market
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `orderbook` | object | Orderbook with yes/no bids and asks |
|
||||
| `orderbook` | object | Orderbook with yes/no bids \(legacy integer counts\) |
|
||||
| ↳ `yes` | array | Yes side bids as tuples \[price_cents, count\] |
|
||||
| ↳ `no` | array | No side bids as tuples \[price_cents, count\] |
|
||||
| ↳ `yes_dollars` | array | Yes side bids as tuples \[dollars_string, count\] |
|
||||
| ↳ `no_dollars` | array | No side bids as tuples \[dollars_string, count\] |
|
||||
| `orderbook_fp` | object | Orderbook with fixed-point counts \(preferred\) |
|
||||
| ↳ `yes_dollars` | array | Yes side bids as tuples \[dollars_string, fp_count_string\] |
|
||||
| ↳ `no_dollars` | array | No side bids as tuples \[dollars_string, fp_count_string\] |
|
||||
|
||||
### `kalshi_get_trades`
|
||||
|
||||
Retrieve recent trades across all markets
|
||||
Retrieve recent trades with additional filtering options (V2 - includes trade_id and count_fp)
|
||||
|
||||
#### Input
|
||||
|
||||
@@ -222,12 +328,12 @@ Retrieve recent trades across all markets
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `trades` | array | Array of trade objects |
|
||||
| `paging` | object | Pagination cursor for fetching more results |
|
||||
| `trades` | array | Array of trade objects with trade_id and count_fp |
|
||||
| `cursor` | string | Pagination cursor for fetching more results |
|
||||
|
||||
### `kalshi_get_candlesticks`
|
||||
|
||||
Retrieve OHLC candlestick data for a specific market
|
||||
Retrieve OHLC candlestick data for a specific market (V2 - full API response)
|
||||
|
||||
#### Input
|
||||
|
||||
@@ -243,7 +349,8 @@ Retrieve OHLC candlestick data for a specific market
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `candlesticks` | array | Array of OHLC candlestick data |
|
||||
| `ticker` | string | Market ticker |
|
||||
| `candlesticks` | array | Array of OHLC candlestick data with nested bid/ask/price objects |
|
||||
|
||||
### `kalshi_get_fills`
|
||||
|
||||
@@ -266,12 +373,12 @@ Retrieve your portfolio
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `fills` | array | Array of fill/trade objects |
|
||||
| `paging` | object | Pagination cursor for fetching more results |
|
||||
| `fills` | array | Array of fill/trade objects with all API fields |
|
||||
| `cursor` | string | Pagination cursor for fetching more results |
|
||||
|
||||
### `kalshi_get_series_by_ticker`
|
||||
|
||||
Retrieve details of a specific market series by ticker
|
||||
Retrieve details of a specific market series by ticker (V2 - exact API response)
|
||||
|
||||
#### Input
|
||||
|
||||
@@ -283,11 +390,25 @@ Retrieve details of a specific market series by ticker
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `series` | object | Series object with details |
|
||||
| `series` | object | Series object with full details matching Kalshi API response |
|
||||
| ↳ `ticker` | string | Series ticker |
|
||||
| ↳ `title` | string | Series title |
|
||||
| ↳ `frequency` | string | Event frequency |
|
||||
| ↳ `category` | string | Series category |
|
||||
| ↳ `tags` | array | Series tags |
|
||||
| ↳ `settlement_sources` | array | Settlement sources |
|
||||
| ↳ `contract_url` | string | Contract URL |
|
||||
| ↳ `contract_terms_url` | string | Contract terms URL |
|
||||
| ↳ `fee_type` | string | Fee type |
|
||||
| ↳ `fee_multiplier` | number | Fee multiplier |
|
||||
| ↳ `additional_prohibitions` | array | Additional prohibitions |
|
||||
| ↳ `product_metadata` | object | Product metadata |
|
||||
| ↳ `volume` | number | Series volume |
|
||||
| ↳ `volume_fp` | number | Volume \(fixed-point\) |
|
||||
|
||||
### `kalshi_get_exchange_status`
|
||||
|
||||
Retrieve the current status of the Kalshi exchange (trading and exchange activity)
|
||||
Retrieve the current status of the Kalshi exchange (V2 - exact API response)
|
||||
|
||||
#### Input
|
||||
|
||||
@@ -298,11 +419,13 @@ Retrieve the current status of the Kalshi exchange (trading and exchange activit
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `status` | object | Exchange status with trading_active and exchange_active flags |
|
||||
| `exchange_active` | boolean | Whether the exchange is active |
|
||||
| `trading_active` | boolean | Whether trading is active |
|
||||
| `exchange_estimated_resume_time` | string | Estimated time when exchange will resume \(if inactive\) |
|
||||
|
||||
### `kalshi_create_order`
|
||||
|
||||
Create a new order on a Kalshi prediction market
|
||||
Create a new order on a Kalshi prediction market (V2 with full API response)
|
||||
|
||||
#### Input
|
||||
|
||||
@@ -332,11 +455,44 @@ Create a new order on a Kalshi prediction market
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `order` | object | The created order object |
|
||||
| `order` | object | The created order object with full API response fields |
|
||||
| ↳ `order_id` | string | Order ID |
|
||||
| ↳ `user_id` | string | User ID |
|
||||
| ↳ `client_order_id` | string | Client order ID |
|
||||
| ↳ `ticker` | string | Market ticker |
|
||||
| ↳ `side` | string | Order side \(yes/no\) |
|
||||
| ↳ `action` | string | Action \(buy/sell\) |
|
||||
| ↳ `type` | string | Order type \(limit/market\) |
|
||||
| ↳ `status` | string | Order status \(resting/canceled/executed\) |
|
||||
| ↳ `yes_price` | number | Yes price in cents |
|
||||
| ↳ `no_price` | number | No price in cents |
|
||||
| ↳ `yes_price_dollars` | string | Yes price in dollars |
|
||||
| ↳ `no_price_dollars` | string | No price in dollars |
|
||||
| ↳ `fill_count` | number | Filled contract count |
|
||||
| ↳ `fill_count_fp` | string | Filled count \(fixed-point\) |
|
||||
| ↳ `remaining_count` | number | Remaining contracts |
|
||||
| ↳ `remaining_count_fp` | string | Remaining count \(fixed-point\) |
|
||||
| ↳ `initial_count` | number | Initial contract count |
|
||||
| ↳ `initial_count_fp` | string | Initial count \(fixed-point\) |
|
||||
| ↳ `taker_fees` | number | Taker fees in cents |
|
||||
| ↳ `maker_fees` | number | Maker fees in cents |
|
||||
| ↳ `taker_fees_dollars` | string | Taker fees in dollars |
|
||||
| ↳ `maker_fees_dollars` | string | Maker fees in dollars |
|
||||
| ↳ `taker_fill_cost` | number | Taker fill cost in cents |
|
||||
| ↳ `maker_fill_cost` | number | Maker fill cost in cents |
|
||||
| ↳ `taker_fill_cost_dollars` | string | Taker fill cost in dollars |
|
||||
| ↳ `maker_fill_cost_dollars` | string | Maker fill cost in dollars |
|
||||
| ↳ `queue_position` | number | Queue position \(deprecated\) |
|
||||
| ↳ `expiration_time` | string | Order expiration time |
|
||||
| ↳ `created_time` | string | Order creation time |
|
||||
| ↳ `last_update_time` | string | Last update time |
|
||||
| ↳ `self_trade_prevention_type` | string | Self-trade prevention type |
|
||||
| ↳ `order_group_id` | string | Order group ID |
|
||||
| ↳ `cancel_order_on_pause` | boolean | Cancel on market pause |
|
||||
|
||||
### `kalshi_cancel_order`
|
||||
|
||||
Cancel an existing order on Kalshi
|
||||
Cancel an existing order on Kalshi (V2 with full API response)
|
||||
|
||||
#### Input
|
||||
|
||||
@@ -350,12 +506,46 @@ Cancel an existing order on Kalshi
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `order` | object | The canceled order object |
|
||||
| `reducedBy` | number | Number of contracts canceled |
|
||||
| `order` | object | The canceled order object with full API response fields |
|
||||
| ↳ `order_id` | string | Order ID |
|
||||
| ↳ `user_id` | string | User ID |
|
||||
| ↳ `client_order_id` | string | Client order ID |
|
||||
| ↳ `ticker` | string | Market ticker |
|
||||
| ↳ `side` | string | Order side \(yes/no\) |
|
||||
| ↳ `action` | string | Action \(buy/sell\) |
|
||||
| ↳ `type` | string | Order type \(limit/market\) |
|
||||
| ↳ `status` | string | Order status \(resting/canceled/executed\) |
|
||||
| ↳ `yes_price` | number | Yes price in cents |
|
||||
| ↳ `no_price` | number | No price in cents |
|
||||
| ↳ `yes_price_dollars` | string | Yes price in dollars |
|
||||
| ↳ `no_price_dollars` | string | No price in dollars |
|
||||
| ↳ `fill_count` | number | Filled contract count |
|
||||
| ↳ `fill_count_fp` | string | Filled count \(fixed-point\) |
|
||||
| ↳ `remaining_count` | number | Remaining contracts |
|
||||
| ↳ `remaining_count_fp` | string | Remaining count \(fixed-point\) |
|
||||
| ↳ `initial_count` | number | Initial contract count |
|
||||
| ↳ `initial_count_fp` | string | Initial count \(fixed-point\) |
|
||||
| ↳ `taker_fees` | number | Taker fees in cents |
|
||||
| ↳ `maker_fees` | number | Maker fees in cents |
|
||||
| ↳ `taker_fees_dollars` | string | Taker fees in dollars |
|
||||
| ↳ `maker_fees_dollars` | string | Maker fees in dollars |
|
||||
| ↳ `taker_fill_cost` | number | Taker fill cost in cents |
|
||||
| ↳ `maker_fill_cost` | number | Maker fill cost in cents |
|
||||
| ↳ `taker_fill_cost_dollars` | string | Taker fill cost in dollars |
|
||||
| ↳ `maker_fill_cost_dollars` | string | Maker fill cost in dollars |
|
||||
| ↳ `queue_position` | number | Queue position \(deprecated\) |
|
||||
| ↳ `expiration_time` | string | Order expiration time |
|
||||
| ↳ `created_time` | string | Order creation time |
|
||||
| ↳ `last_update_time` | string | Last update time |
|
||||
| ↳ `self_trade_prevention_type` | string | Self-trade prevention type |
|
||||
| ↳ `order_group_id` | string | Order group ID |
|
||||
| ↳ `cancel_order_on_pause` | boolean | Cancel on market pause |
|
||||
| `reduced_by` | number | Number of contracts canceled |
|
||||
| `reduced_by_fp` | string | Number of contracts canceled in fixed-point format |
|
||||
|
||||
### `kalshi_amend_order`
|
||||
|
||||
Modify the price or quantity of an existing order on Kalshi
|
||||
Modify the price or quantity of an existing order on Kalshi (V2 with full API response)
|
||||
|
||||
#### Input
|
||||
|
||||
@@ -379,6 +569,63 @@ Modify the price or quantity of an existing order on Kalshi
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `order` | object | The amended order object |
|
||||
| `old_order` | object | The original order object before amendment |
|
||||
| ↳ `order_id` | string | Order ID |
|
||||
| ↳ `user_id` | string | User ID |
|
||||
| ↳ `ticker` | string | Market ticker |
|
||||
| ↳ `event_ticker` | string | Event ticker |
|
||||
| ↳ `status` | string | Order status |
|
||||
| ↳ `side` | string | Order side \(yes/no\) |
|
||||
| ↳ `type` | string | Order type \(limit/market\) |
|
||||
| ↳ `yes_price` | number | Yes price in cents |
|
||||
| ↳ `no_price` | number | No price in cents |
|
||||
| ↳ `action` | string | Action \(buy/sell\) |
|
||||
| ↳ `count` | number | Number of contracts |
|
||||
| ↳ `remaining_count` | number | Remaining contracts |
|
||||
| ↳ `created_time` | string | Order creation time |
|
||||
| ↳ `expiration_time` | string | Order expiration time |
|
||||
| ↳ `order_group_id` | string | Order group ID |
|
||||
| ↳ `client_order_id` | string | Client order ID |
|
||||
| ↳ `place_count` | number | Place count |
|
||||
| ↳ `decrease_count` | number | Decrease count |
|
||||
| ↳ `queue_position` | number | Queue position |
|
||||
| ↳ `maker_fill_count` | number | Maker fill count |
|
||||
| ↳ `taker_fill_count` | number | Taker fill count |
|
||||
| ↳ `maker_fees` | number | Maker fees |
|
||||
| ↳ `taker_fees` | number | Taker fees |
|
||||
| ↳ `last_update_time` | string | Last update time |
|
||||
| ↳ `take_profit_order_id` | string | Take profit order ID |
|
||||
| ↳ `stop_loss_order_id` | string | Stop loss order ID |
|
||||
| ↳ `amend_count` | number | Amend count |
|
||||
| ↳ `amend_taker_fill_count` | number | Amend taker fill count |
|
||||
| `order` | object | The amended order object with full API response fields |
|
||||
| ↳ `order_id` | string | Order ID |
|
||||
| ↳ `user_id` | string | User ID |
|
||||
| ↳ `ticker` | string | Market ticker |
|
||||
| ↳ `event_ticker` | string | Event ticker |
|
||||
| ↳ `status` | string | Order status |
|
||||
| ↳ `side` | string | Order side \(yes/no\) |
|
||||
| ↳ `type` | string | Order type \(limit/market\) |
|
||||
| ↳ `yes_price` | number | Yes price in cents |
|
||||
| ↳ `no_price` | number | No price in cents |
|
||||
| ↳ `action` | string | Action \(buy/sell\) |
|
||||
| ↳ `count` | number | Number of contracts |
|
||||
| ↳ `remaining_count` | number | Remaining contracts |
|
||||
| ↳ `created_time` | string | Order creation time |
|
||||
| ↳ `expiration_time` | string | Order expiration time |
|
||||
| ↳ `order_group_id` | string | Order group ID |
|
||||
| ↳ `client_order_id` | string | Client order ID |
|
||||
| ↳ `place_count` | number | Place count |
|
||||
| ↳ `decrease_count` | number | Decrease count |
|
||||
| ↳ `queue_position` | number | Queue position |
|
||||
| ↳ `maker_fill_count` | number | Maker fill count |
|
||||
| ↳ `taker_fill_count` | number | Taker fill count |
|
||||
| ↳ `maker_fees` | number | Maker fees |
|
||||
| ↳ `taker_fees` | number | Taker fees |
|
||||
| ↳ `last_update_time` | string | Last update time |
|
||||
| ↳ `take_profit_order_id` | string | Take profit order ID |
|
||||
| ↳ `stop_loss_order_id` | string | Stop loss order ID |
|
||||
| ↳ `amend_count` | number | Amend count |
|
||||
| ↳ `amend_taker_fill_count` | number | Amend taker fill count |
|
||||
|
||||
|
||||
|
||||
@@ -97,7 +97,6 @@
|
||||
"shopify",
|
||||
"slack",
|
||||
"smtp",
|
||||
"spotify",
|
||||
"sqs",
|
||||
"ssh",
|
||||
"stagehand",
|
||||
|
||||
@@ -29,7 +29,7 @@ By using these documented API endpoints, you can seamlessly integrate Polymarket
|
||||
|
||||
## Usage Instructions
|
||||
|
||||
Integrate Polymarket prediction markets into the workflow. Can get markets, market, events, event, tags, series, orderbook, price, midpoint, price history, last trade price, spread, tick size, positions, trades, and search.
|
||||
Integrate Polymarket prediction markets into the workflow. Can get markets, market, events, event, tags, series, orderbook, price, midpoint, price history, last trade price, spread, tick size, positions, trades, activity, leaderboard, holders, and search.
|
||||
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ Retrieve a list of prediction markets from Polymarket with optional filtering
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `closed` | string | No | Filter by closed status \(true/false\). Use false for active markets only. |
|
||||
| `closed` | string | No | Filter by closed status \(true/false\). Use false for open markets only. |
|
||||
| `order` | string | No | Sort field \(e.g., volumeNum, liquidityNum, startDate, endDate, createdAt\) |
|
||||
| `ascending` | string | No | Sort direction \(true for ascending, false for descending\) |
|
||||
| `tagId` | string | No | Filter by tag ID |
|
||||
@@ -55,6 +55,21 @@ Retrieve a list of prediction markets from Polymarket with optional filtering
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `markets` | array | Array of market objects |
|
||||
| ↳ `id` | string | Market ID |
|
||||
| ↳ `question` | string | Market question |
|
||||
| ↳ `conditionId` | string | Condition ID |
|
||||
| ↳ `slug` | string | Market slug |
|
||||
| ↳ `endDate` | string | End date |
|
||||
| ↳ `image` | string | Market image URL |
|
||||
| ↳ `outcomes` | string | Outcomes JSON string |
|
||||
| ↳ `outcomePrices` | string | Outcome prices JSON string |
|
||||
| ↳ `volume` | string | Total volume |
|
||||
| ↳ `liquidity` | string | Total liquidity |
|
||||
| ↳ `active` | boolean | Whether market is active |
|
||||
| ↳ `closed` | boolean | Whether market is closed |
|
||||
| ↳ `volumeNum` | number | Volume as number |
|
||||
| ↳ `liquidityNum` | number | Liquidity as number |
|
||||
| ↳ `clobTokenIds` | array | CLOB token IDs |
|
||||
|
||||
### `polymarket_get_market`
|
||||
|
||||
@@ -72,6 +87,28 @@ Retrieve details of a specific prediction market by ID or slug
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `market` | object | Market object with details |
|
||||
| ↳ `id` | string | Market ID |
|
||||
| ↳ `question` | string | Market question |
|
||||
| ↳ `conditionId` | string | Condition ID |
|
||||
| ↳ `slug` | string | Market slug |
|
||||
| ↳ `resolutionSource` | string | Resolution source |
|
||||
| ↳ `endDate` | string | End date |
|
||||
| ↳ `startDate` | string | Start date |
|
||||
| ↳ `image` | string | Market image URL |
|
||||
| ↳ `icon` | string | Market icon URL |
|
||||
| ↳ `description` | string | Market description |
|
||||
| ↳ `outcomes` | string | Outcomes JSON string |
|
||||
| ↳ `outcomePrices` | string | Outcome prices JSON string |
|
||||
| ↳ `volume` | string | Total volume |
|
||||
| ↳ `liquidity` | string | Total liquidity |
|
||||
| ↳ `active` | boolean | Whether market is active |
|
||||
| ↳ `closed` | boolean | Whether market is closed |
|
||||
| ↳ `archived` | boolean | Whether market is archived |
|
||||
| ↳ `volumeNum` | number | Volume as number |
|
||||
| ↳ `liquidityNum` | number | Liquidity as number |
|
||||
| ↳ `clobTokenIds` | array | CLOB token IDs |
|
||||
| ↳ `acceptingOrders` | boolean | Whether accepting orders |
|
||||
| ↳ `negRisk` | boolean | Whether negative risk |
|
||||
|
||||
### `polymarket_get_events`
|
||||
|
||||
@@ -81,7 +118,7 @@ Retrieve a list of events from Polymarket with optional filtering
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `closed` | string | No | Filter by closed status \(true/false\). Use false for active events only. |
|
||||
| `closed` | string | No | Filter by closed status \(true/false\). Use false for open events only. |
|
||||
| `order` | string | No | Sort field \(e.g., volume, liquidity, startDate, endDate, createdAt\) |
|
||||
| `ascending` | string | No | Sort direction \(true for ascending, false for descending\) |
|
||||
| `tagId` | string | No | Filter by tag ID |
|
||||
@@ -93,6 +130,21 @@ Retrieve a list of events from Polymarket with optional filtering
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `events` | array | Array of event objects |
|
||||
| ↳ `id` | string | Event ID |
|
||||
| ↳ `ticker` | string | Event ticker |
|
||||
| ↳ `slug` | string | Event slug |
|
||||
| ↳ `title` | string | Event title |
|
||||
| ↳ `description` | string | Event description |
|
||||
| ↳ `startDate` | string | Start date |
|
||||
| ↳ `endDate` | string | End date |
|
||||
| ↳ `image` | string | Event image URL |
|
||||
| ↳ `icon` | string | Event icon URL |
|
||||
| ↳ `active` | boolean | Whether event is active |
|
||||
| ↳ `closed` | boolean | Whether event is closed |
|
||||
| ↳ `archived` | boolean | Whether event is archived |
|
||||
| ↳ `liquidity` | number | Total liquidity |
|
||||
| ↳ `volume` | number | Total volume |
|
||||
| ↳ `markets` | array | Array of markets in this event |
|
||||
|
||||
### `polymarket_get_event`
|
||||
|
||||
@@ -110,6 +162,24 @@ Retrieve details of a specific event by ID or slug
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `event` | object | Event object with details |
|
||||
| ↳ `id` | string | Event ID |
|
||||
| ↳ `ticker` | string | Event ticker |
|
||||
| ↳ `slug` | string | Event slug |
|
||||
| ↳ `title` | string | Event title |
|
||||
| ↳ `description` | string | Event description |
|
||||
| ↳ `startDate` | string | Start date |
|
||||
| ↳ `creationDate` | string | Creation date |
|
||||
| ↳ `endDate` | string | End date |
|
||||
| ↳ `image` | string | Event image URL |
|
||||
| ↳ `icon` | string | Event icon URL |
|
||||
| ↳ `active` | boolean | Whether event is active |
|
||||
| ↳ `closed` | boolean | Whether event is closed |
|
||||
| ↳ `archived` | boolean | Whether event is archived |
|
||||
| ↳ `liquidity` | number | Total liquidity |
|
||||
| ↳ `volume` | number | Total volume |
|
||||
| ↳ `openInterest` | number | Open interest |
|
||||
| ↳ `commentCount` | number | Comment count |
|
||||
| ↳ `markets` | array | Array of markets in this event |
|
||||
|
||||
### `polymarket_get_tags`
|
||||
|
||||
@@ -126,7 +196,12 @@ Retrieve available tags for filtering markets from Polymarket
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `tags` | array | Array of tag objects with id, label, and slug |
|
||||
| `tags` | array | Array of tag objects |
|
||||
| ↳ `id` | string | Tag ID |
|
||||
| ↳ `label` | string | Tag label |
|
||||
| ↳ `slug` | string | Tag slug |
|
||||
| ↳ `createdAt` | string | Creation timestamp |
|
||||
| ↳ `updatedAt` | string | Last update timestamp |
|
||||
|
||||
### `polymarket_search`
|
||||
|
||||
@@ -138,13 +213,28 @@ Search for markets, events, and profiles on Polymarket
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `query` | string | Yes | Search query term |
|
||||
| `limit` | string | No | Number of results per page \(max 50\) |
|
||||
| `offset` | string | No | Pagination offset |
|
||||
| `page` | string | No | Page number for pagination \(1-indexed\) |
|
||||
| `cache` | string | No | Enable caching \(true/false\) |
|
||||
| `eventsStatus` | string | No | Filter events by status |
|
||||
| `limitPerType` | string | No | Limit results per type \(markets, events, profiles\) |
|
||||
| `eventsTag` | string | No | Filter by event tags \(comma-separated\) |
|
||||
| `sort` | string | No | Sort field |
|
||||
| `ascending` | string | No | Sort direction \(true for ascending, false for descending\) |
|
||||
| `searchTags` | string | No | Include tags in search results \(true/false\) |
|
||||
| `searchProfiles` | string | No | Include profiles in search results \(true/false\) |
|
||||
| `recurrence` | string | No | Filter by recurrence type |
|
||||
| `excludeTagId` | string | No | Exclude events with these tag IDs \(comma-separated\) |
|
||||
| `keepClosedMarkets` | string | No | Include closed markets in results \(0 or 1\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `results` | object | Search results containing markets, events, and profiles arrays |
|
||||
| `results` | object | Search results containing markets, events, tags, and profiles arrays |
|
||||
| ↳ `markets` | array | Array of matching market objects |
|
||||
| ↳ `events` | array | Array of matching event objects |
|
||||
| ↳ `tags` | array | Array of matching tag objects |
|
||||
| ↳ `profiles` | array | Array of matching profile objects |
|
||||
|
||||
### `polymarket_get_series`
|
||||
|
||||
@@ -162,6 +252,21 @@ Retrieve series (related market groups) from Polymarket
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `series` | array | Array of series objects |
|
||||
| ↳ `id` | string | Series ID |
|
||||
| ↳ `ticker` | string | Series ticker |
|
||||
| ↳ `slug` | string | Series slug |
|
||||
| ↳ `title` | string | Series title |
|
||||
| ↳ `seriesType` | string | Series type |
|
||||
| ↳ `recurrence` | string | Recurrence pattern |
|
||||
| ↳ `image` | string | Series image URL |
|
||||
| ↳ `icon` | string | Series icon URL |
|
||||
| ↳ `active` | boolean | Whether series is active |
|
||||
| ↳ `closed` | boolean | Whether series is closed |
|
||||
| ↳ `archived` | boolean | Whether series is archived |
|
||||
| ↳ `featured` | boolean | Whether series is featured |
|
||||
| ↳ `volume` | number | Total volume |
|
||||
| ↳ `liquidity` | number | Total liquidity |
|
||||
| ↳ `eventCount` | number | Number of events in series |
|
||||
|
||||
### `polymarket_get_series_by_id`
|
||||
|
||||
@@ -178,6 +283,23 @@ Retrieve a specific series (related market group) by ID from Polymarket
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `series` | object | Series object with details |
|
||||
| ↳ `id` | string | Series ID |
|
||||
| ↳ `ticker` | string | Series ticker |
|
||||
| ↳ `slug` | string | Series slug |
|
||||
| ↳ `title` | string | Series title |
|
||||
| ↳ `seriesType` | string | Series type |
|
||||
| ↳ `recurrence` | string | Recurrence pattern |
|
||||
| ↳ `image` | string | Series image URL |
|
||||
| ↳ `icon` | string | Series icon URL |
|
||||
| ↳ `active` | boolean | Whether series is active |
|
||||
| ↳ `closed` | boolean | Whether series is closed |
|
||||
| ↳ `archived` | boolean | Whether series is archived |
|
||||
| ↳ `featured` | boolean | Whether series is featured |
|
||||
| ↳ `volume` | number | Total volume |
|
||||
| ↳ `liquidity` | number | Total liquidity |
|
||||
| ↳ `commentCount` | number | Comment count |
|
||||
| ↳ `eventCount` | number | Number of events in series |
|
||||
| ↳ `events` | array | Array of events in this series |
|
||||
|
||||
### `polymarket_get_orderbook`
|
||||
|
||||
@@ -194,6 +316,21 @@ Retrieve the order book summary for a specific token
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `orderbook` | object | Order book with bids and asks arrays |
|
||||
| ↳ `market` | string | Market identifier |
|
||||
| ↳ `asset_id` | string | Asset token ID |
|
||||
| ↳ `hash` | string | Order book hash |
|
||||
| ↳ `timestamp` | string | Timestamp |
|
||||
| ↳ `bids` | array | Bid orders |
|
||||
| ↳ `price` | string | Bid price |
|
||||
| ↳ `size` | string | Bid size |
|
||||
| ↳ `price` | string | Ask price |
|
||||
| ↳ `size` | string | Ask size |
|
||||
| ↳ `asks` | array | Ask orders |
|
||||
| ↳ `price` | string | Ask price |
|
||||
| ↳ `size` | string | Ask size |
|
||||
| ↳ `min_order_size` | string | Minimum order size |
|
||||
| ↳ `tick_size` | string | Tick size |
|
||||
| ↳ `neg_risk` | boolean | Whether negative risk |
|
||||
|
||||
### `polymarket_get_price`
|
||||
|
||||
@@ -246,7 +383,9 @@ Retrieve historical price data for a specific market token
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `history` | array | Array of price history entries with timestamp \(t\) and price \(p\) |
|
||||
| `history` | array | Array of price history entries |
|
||||
| ↳ `t` | number | Unix timestamp |
|
||||
| ↳ `p` | number | Price at timestamp |
|
||||
|
||||
### `polymarket_get_last_trade_price`
|
||||
|
||||
@@ -263,6 +402,7 @@ Retrieve the last trade price for a specific token
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `price` | string | Last trade price |
|
||||
| `side` | string | Side of the last trade \(BUY or SELL\) |
|
||||
|
||||
### `polymarket_get_spread`
|
||||
|
||||
@@ -278,7 +418,8 @@ Retrieve the bid-ask spread for a specific token
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `spread` | object | Bid-ask spread with bid and ask prices |
|
||||
| `spread` | object | Spread value between bid and ask |
|
||||
| ↳ `spread` | string | The spread value |
|
||||
|
||||
### `polymarket_get_tick_size`
|
||||
|
||||
@@ -305,13 +446,47 @@ Retrieve user positions from Polymarket
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `user` | string | Yes | User wallet address |
|
||||
| `market` | string | No | Optional market ID to filter positions |
|
||||
| `market` | string | No | Condition IDs to filter positions \(comma-separated, mutually exclusive with eventId\) |
|
||||
| `eventId` | string | No | Event ID to filter positions \(mutually exclusive with market\) |
|
||||
| `sizeThreshold` | string | No | Minimum position size threshold \(default: 1\) |
|
||||
| `redeemable` | string | No | Filter for redeemable positions only \(true/false\) |
|
||||
| `mergeable` | string | No | Filter for mergeable positions only \(true/false\) |
|
||||
| `sortBy` | string | No | Sort field \(TOKENS, CURRENT, INITIAL, CASHPNL, PERCENTPNL, TITLE, RESOLVING, PRICE, AVGPRICE\) |
|
||||
| `sortDirection` | string | No | Sort direction \(ASC or DESC\) |
|
||||
| `title` | string | No | Search filter by title |
|
||||
| `limit` | string | No | Number of results per page |
|
||||
| `offset` | string | No | Pagination offset |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `positions` | array | Array of position objects |
|
||||
| ↳ `proxyWallet` | string | Proxy wallet address |
|
||||
| ↳ `asset` | string | Asset token ID |
|
||||
| ↳ `conditionId` | string | Condition ID |
|
||||
| ↳ `size` | number | Position size |
|
||||
| ↳ `avgPrice` | number | Average price |
|
||||
| ↳ `initialValue` | number | Initial value |
|
||||
| ↳ `currentValue` | number | Current value |
|
||||
| ↳ `cashPnl` | number | Cash profit/loss |
|
||||
| ↳ `percentPnl` | number | Percent profit/loss |
|
||||
| ↳ `totalBought` | number | Total bought |
|
||||
| ↳ `realizedPnl` | number | Realized profit/loss |
|
||||
| ↳ `percentRealizedPnl` | number | Percent realized profit/loss |
|
||||
| ↳ `curPrice` | number | Current price |
|
||||
| ↳ `redeemable` | boolean | Whether position is redeemable |
|
||||
| ↳ `mergeable` | boolean | Whether position is mergeable |
|
||||
| ↳ `title` | string | Market title |
|
||||
| ↳ `slug` | string | Market slug |
|
||||
| ↳ `icon` | string | Market icon URL |
|
||||
| ↳ `eventSlug` | string | Event slug |
|
||||
| ↳ `outcome` | string | Outcome name |
|
||||
| ↳ `outcomeIndex` | number | Outcome index |
|
||||
| ↳ `oppositeOutcome` | string | Opposite outcome name |
|
||||
| ↳ `oppositeAsset` | string | Opposite asset token ID |
|
||||
| ↳ `endDate` | string | End date |
|
||||
| ↳ `negativeRisk` | boolean | Whether negative risk |
|
||||
|
||||
### `polymarket_get_trades`
|
||||
|
||||
@@ -322,8 +497,13 @@ Retrieve trade history from Polymarket
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `user` | string | No | User wallet address to filter trades |
|
||||
| `market` | string | No | Market ID to filter trades |
|
||||
| `limit` | string | No | Number of results per page \(max 50\) |
|
||||
| `market` | string | No | Market/condition ID to filter trades \(mutually exclusive with eventId\) |
|
||||
| `eventId` | string | No | Event ID to filter trades \(mutually exclusive with market\) |
|
||||
| `side` | string | No | Trade direction filter \(BUY or SELL\) |
|
||||
| `takerOnly` | string | No | Filter for taker trades only \(true/false, default: true\) |
|
||||
| `filterType` | string | No | Filter type \(CASH or TOKENS\) - requires filterAmount |
|
||||
| `filterAmount` | string | No | Filter amount threshold - requires filterType |
|
||||
| `limit` | string | No | Number of results per page \(default: 100, max: 10000\) |
|
||||
| `offset` | string | No | Pagination offset \(skip this many results\) |
|
||||
|
||||
#### Output
|
||||
@@ -331,5 +511,141 @@ Retrieve trade history from Polymarket
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `trades` | array | Array of trade objects |
|
||||
| ↳ `proxyWallet` | string | Proxy wallet address |
|
||||
| ↳ `side` | string | Trade side \(BUY or SELL\) |
|
||||
| ↳ `asset` | string | Asset token ID |
|
||||
| ↳ `conditionId` | string | Condition ID |
|
||||
| ↳ `size` | number | Trade size |
|
||||
| ↳ `price` | number | Trade price |
|
||||
| ↳ `timestamp` | number | Unix timestamp |
|
||||
| ↳ `title` | string | Market title |
|
||||
| ↳ `slug` | string | Market slug |
|
||||
| ↳ `icon` | string | Market icon URL |
|
||||
| ↳ `eventSlug` | string | Event slug |
|
||||
| ↳ `outcome` | string | Outcome name |
|
||||
| ↳ `outcomeIndex` | number | Outcome index |
|
||||
| ↳ `name` | string | Trader name |
|
||||
| ↳ `pseudonym` | string | Trader pseudonym |
|
||||
| ↳ `bio` | string | Trader bio |
|
||||
| ↳ `profileImage` | string | Profile image URL |
|
||||
| ↳ `profileImageOptimized` | string | Optimized profile image URL |
|
||||
| ↳ `transactionHash` | string | Transaction hash |
|
||||
|
||||
### `polymarket_get_activity`
|
||||
|
||||
Retrieve on-chain activity for a user including trades, splits, merges, redemptions, rewards, and conversions
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `user` | string | Yes | User wallet address \(0x-prefixed\) |
|
||||
| `limit` | string | No | Maximum results \(default: 100, max: 500\) |
|
||||
| `offset` | string | No | Pagination offset \(default: 0, max: 10000\) |
|
||||
| `market` | string | No | Comma-separated condition IDs \(mutually exclusive with eventId\) |
|
||||
| `eventId` | string | No | Comma-separated event IDs \(mutually exclusive with market\) |
|
||||
| `type` | string | No | Activity type filter: TRADE, SPLIT, MERGE, REDEEM, REWARD, CONVERSION, MAKER_REBATE |
|
||||
| `start` | number | No | Start timestamp \(Unix seconds\) |
|
||||
| `end` | number | No | End timestamp \(Unix seconds\) |
|
||||
| `sortBy` | string | No | Sort field: TIMESTAMP, TOKENS, or CASH \(default: TIMESTAMP\) |
|
||||
| `sortDirection` | string | No | Sort direction: ASC or DESC \(default: DESC\) |
|
||||
| `side` | string | No | Trade side filter: BUY or SELL \(only applies to trades\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `activity` | array | Array of activity entries |
|
||||
| ↳ `proxyWallet` | string | User proxy wallet address |
|
||||
| ↳ `timestamp` | number | Unix timestamp of activity |
|
||||
| ↳ `conditionId` | string | Market condition ID |
|
||||
| ↳ `type` | string | Activity type \(TRADE, SPLIT, MERGE, REDEEM, REWARD, CONVERSION\) |
|
||||
| ↳ `size` | number | Size in tokens |
|
||||
| ↳ `usdcSize` | number | Size in USDC |
|
||||
| ↳ `transactionHash` | string | Blockchain transaction hash |
|
||||
| ↳ `price` | number | Price \(for trades\) |
|
||||
| ↳ `asset` | string | Asset/token ID |
|
||||
| ↳ `side` | string | Trade side \(BUY/SELL\) |
|
||||
| ↳ `outcomeIndex` | number | Outcome index |
|
||||
| ↳ `title` | string | Market title |
|
||||
| ↳ `slug` | string | Market slug |
|
||||
| ↳ `icon` | string | Market icon URL |
|
||||
| ↳ `eventSlug` | string | Event slug |
|
||||
| ↳ `outcome` | string | Outcome name |
|
||||
| ↳ `name` | string | User display name |
|
||||
| ↳ `pseudonym` | string | User pseudonym |
|
||||
| ↳ `bio` | string | User bio |
|
||||
| ↳ `profileImage` | string | User profile image URL |
|
||||
| ↳ `profileImageOptimized` | string | Optimized profile image URL |
|
||||
|
||||
### `polymarket_get_leaderboard`
|
||||
|
||||
Retrieve trader leaderboard rankings by profit/loss or volume
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `category` | string | No | Category filter: OVERALL, POLITICS, SPORTS, CRYPTO, CULTURE, MENTIONS, WEATHER, ECONOMICS, TECH, FINANCE \(default: OVERALL\) |
|
||||
| `timePeriod` | string | No | Time period: DAY, WEEK, MONTH, ALL \(default: DAY\) |
|
||||
| `orderBy` | string | No | Order by: PNL or VOL \(default: PNL\) |
|
||||
| `limit` | string | No | Number of results \(1-50, default: 25\) |
|
||||
| `offset` | string | No | Pagination offset \(0-1000, default: 0\) |
|
||||
| `user` | string | No | Filter by specific user wallet address |
|
||||
| `userName` | string | No | Filter by username |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `leaderboard` | array | Array of leaderboard entries |
|
||||
| ↳ `rank` | string | Leaderboard rank position |
|
||||
| ↳ `proxyWallet` | string | User proxy wallet address |
|
||||
| ↳ `userName` | string | User display name |
|
||||
| ↳ `vol` | number | Trading volume |
|
||||
| ↳ `pnl` | number | Profit and loss |
|
||||
| ↳ `profileImage` | string | User profile image URL |
|
||||
| ↳ `xUsername` | string | Twitter/X username |
|
||||
| ↳ `verifiedBadge` | boolean | Whether user has verified badge |
|
||||
|
||||
### `polymarket_get_holders`
|
||||
|
||||
Retrieve top holders of a specific market token
|
||||
|
||||
#### Input
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `market` | string | Yes | Comma-separated list of condition IDs |
|
||||
| `limit` | string | No | Number of holders to return \(0-20, default: 20\) |
|
||||
| `minBalance` | string | No | Minimum balance threshold \(default: 1\) |
|
||||
|
||||
#### Output
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `holders` | array | Array of market holder groups by token |
|
||||
| ↳ `token` | string | Token/asset ID |
|
||||
| ↳ `holders` | array | Array of holders for this token |
|
||||
| ↳ `proxyWallet` | string | Holder wallet address |
|
||||
| ↳ `bio` | string | Holder bio |
|
||||
| ↳ `asset` | string | Asset ID |
|
||||
| ↳ `pseudonym` | string | Holder pseudonym |
|
||||
| ↳ `amount` | number | Amount held |
|
||||
| ↳ `displayUsernamePublic` | boolean | Whether username is publicly displayed |
|
||||
| ↳ `outcomeIndex` | number | Outcome index |
|
||||
| ↳ `name` | string | Holder display name |
|
||||
| ↳ `profileImage` | string | Profile image URL |
|
||||
| ↳ `profileImageOptimized` | string | Optimized profile image URL |
|
||||
| ↳ `proxyWallet` | string | Holder wallet address |
|
||||
| ↳ `bio` | string | Holder bio |
|
||||
| ↳ `asset` | string | Asset ID |
|
||||
| ↳ `pseudonym` | string | Holder pseudonym |
|
||||
| ↳ `amount` | number | Amount held |
|
||||
| ↳ `displayUsernamePublic` | boolean | Whether username is publicly displayed |
|
||||
| ↳ `outcomeIndex` | number | Outcome index |
|
||||
| ↳ `name` | string | Holder display name |
|
||||
| ↳ `profileImage` | string | Profile image URL |
|
||||
| ↳ `profileImageOptimized` | string | Optimized profile image URL |
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -299,7 +299,7 @@ Upload a file to a Supabase storage bucket
|
||||
| `bucket` | string | Yes | The name of the storage bucket |
|
||||
| `fileName` | string | Yes | The name of the file \(e.g., "document.pdf", "image.jpg"\) |
|
||||
| `path` | string | No | Optional folder path \(e.g., "folder/subfolder/"\) |
|
||||
| `fileContent` | string | Yes | The file content \(base64 encoded for binary files, or plain text\) |
|
||||
| `fileData` | json | Yes | File to upload - UserFile object \(basic mode\) or string content \(advanced mode: base64 or plain text\). Supports data URLs. |
|
||||
| `contentType` | string | No | MIME type of the file \(e.g., "image/jpeg", "text/plain"\) |
|
||||
| `upsert` | boolean | No | If true, overwrites existing file \(default: false\) |
|
||||
| `apiKey` | string | Yes | Your Supabase service role secret key |
|
||||
@@ -309,7 +309,7 @@ Upload a file to a Supabase storage bucket
|
||||
| Parameter | Type | Description |
|
||||
| --------- | ---- | ----------- |
|
||||
| `message` | string | Operation status message |
|
||||
| `results` | object | Upload result including file path and metadata |
|
||||
| `results` | object | Upload result including file path, bucket, and public URL |
|
||||
|
||||
### `supabase_storage_download`
|
||||
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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)' },
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import { KalshiIcon } from '@/components/icons'
|
||||
import type { BlockConfig } from '@/blocks/types'
|
||||
import { AuthMode } from '@/blocks/types'
|
||||
import { createVersionedToolSelector } from '@/blocks/utils'
|
||||
|
||||
export const KalshiBlock: BlockConfig = {
|
||||
type: 'kalshi',
|
||||
name: 'Kalshi',
|
||||
name: 'Kalshi (Legacy)',
|
||||
description: 'Access prediction markets and trade on Kalshi',
|
||||
longDescription:
|
||||
'Integrate Kalshi prediction markets into the workflow. Can get markets, market, events, event, balance, positions, orders, orderbook, trades, candlesticks, fills, series, exchange status, and place/cancel/amend trades.',
|
||||
docsLink: 'https://docs.sim.ai/tools/kalshi',
|
||||
authMode: AuthMode.ApiKey,
|
||||
category: 'tools',
|
||||
hideFromToolbar: true,
|
||||
bgColor: '#09C285',
|
||||
icon: KalshiIcon,
|
||||
subBlocks: [
|
||||
@@ -349,8 +351,14 @@ Return ONLY the numeric timestamp (seconds since Unix epoch) - no explanations,
|
||||
id: 'count',
|
||||
title: 'Contracts',
|
||||
type: 'short-input',
|
||||
placeholder: 'Number of contracts',
|
||||
required: true,
|
||||
placeholder: 'Number of contracts (or use countFp)',
|
||||
condition: { field: 'operation', value: ['create_order'] },
|
||||
},
|
||||
{
|
||||
id: 'countFp',
|
||||
title: 'Contracts (Fixed-Point)',
|
||||
type: 'short-input',
|
||||
placeholder: 'Fixed-point count (e.g., "10.50")',
|
||||
condition: { field: 'operation', value: ['create_order'] },
|
||||
},
|
||||
{
|
||||
@@ -674,3 +682,143 @@ Return ONLY the numeric timestamp (seconds since Unix epoch) - no explanations,
|
||||
paging: { type: 'json', description: 'Pagination cursor for fetching more results' },
|
||||
},
|
||||
}
|
||||
|
||||
export const KalshiV2Block: BlockConfig = {
|
||||
...KalshiBlock,
|
||||
type: 'kalshi_v2',
|
||||
name: 'Kalshi',
|
||||
description: 'Access prediction markets and trade on Kalshi',
|
||||
longDescription:
|
||||
'Integrate Kalshi prediction markets into the workflow. Can get markets, market, events, event, balance, positions, orders, orderbook, trades, candlesticks, fills, series, exchange status, and place/cancel/amend trades.',
|
||||
hideFromToolbar: false,
|
||||
tools: {
|
||||
...KalshiBlock.tools,
|
||||
access: [
|
||||
'kalshi_get_markets_v2',
|
||||
'kalshi_get_market_v2',
|
||||
'kalshi_get_events_v2',
|
||||
'kalshi_get_event_v2',
|
||||
'kalshi_get_balance_v2',
|
||||
'kalshi_get_positions_v2',
|
||||
'kalshi_get_orders_v2',
|
||||
'kalshi_get_order_v2',
|
||||
'kalshi_get_orderbook_v2',
|
||||
'kalshi_get_trades_v2',
|
||||
'kalshi_get_candlesticks_v2',
|
||||
'kalshi_get_fills_v2',
|
||||
'kalshi_get_series_by_ticker_v2',
|
||||
'kalshi_get_exchange_status_v2',
|
||||
'kalshi_create_order_v2',
|
||||
'kalshi_cancel_order_v2',
|
||||
'kalshi_amend_order_v2',
|
||||
],
|
||||
config: {
|
||||
...KalshiBlock.tools!.config,
|
||||
tool: createVersionedToolSelector({
|
||||
baseToolSelector: (params) => {
|
||||
switch (params.operation) {
|
||||
case 'get_markets':
|
||||
return 'kalshi_get_markets'
|
||||
case 'get_market':
|
||||
return 'kalshi_get_market'
|
||||
case 'get_events':
|
||||
return 'kalshi_get_events'
|
||||
case 'get_event':
|
||||
return 'kalshi_get_event'
|
||||
case 'get_balance':
|
||||
return 'kalshi_get_balance'
|
||||
case 'get_positions':
|
||||
return 'kalshi_get_positions'
|
||||
case 'get_orders':
|
||||
return 'kalshi_get_orders'
|
||||
case 'get_order':
|
||||
return 'kalshi_get_order'
|
||||
case 'get_orderbook':
|
||||
return 'kalshi_get_orderbook'
|
||||
case 'get_trades':
|
||||
return 'kalshi_get_trades'
|
||||
case 'get_candlesticks':
|
||||
return 'kalshi_get_candlesticks'
|
||||
case 'get_fills':
|
||||
return 'kalshi_get_fills'
|
||||
case 'get_series_by_ticker':
|
||||
return 'kalshi_get_series_by_ticker'
|
||||
case 'get_exchange_status':
|
||||
return 'kalshi_get_exchange_status'
|
||||
case 'create_order':
|
||||
return 'kalshi_create_order'
|
||||
case 'cancel_order':
|
||||
return 'kalshi_cancel_order'
|
||||
case 'amend_order':
|
||||
return 'kalshi_amend_order'
|
||||
default:
|
||||
return 'kalshi_get_markets'
|
||||
}
|
||||
},
|
||||
suffix: '_v2',
|
||||
fallbackToolId: 'kalshi_get_markets_v2',
|
||||
}),
|
||||
},
|
||||
},
|
||||
outputs: {
|
||||
// List operations (V2 uses snake_case and flat cursor)
|
||||
markets: { type: 'json', description: 'Array of market objects (get_markets)' },
|
||||
events: { type: 'json', description: 'Array of event objects (get_events)' },
|
||||
orders: { type: 'json', description: 'Array of order objects (get_orders)' },
|
||||
market_positions: {
|
||||
type: 'json',
|
||||
description: 'Array of market position objects (get_positions)',
|
||||
},
|
||||
event_positions: {
|
||||
type: 'json',
|
||||
description: 'Array of event position objects (get_positions)',
|
||||
},
|
||||
fills: { type: 'json', description: 'Array of fill objects (get_fills)' },
|
||||
trades: { type: 'json', description: 'Array of trade objects (get_trades)' },
|
||||
candlesticks: {
|
||||
type: 'json',
|
||||
description: 'Array of candlestick data with yes_bid/yes_ask/price nested objects',
|
||||
},
|
||||
milestones: {
|
||||
type: 'json',
|
||||
description: 'Array of milestone objects (get_events with milestones)',
|
||||
},
|
||||
// Single item operations
|
||||
market: { type: 'json', description: 'Single market object (get_market)' },
|
||||
event: { type: 'json', description: 'Single event object (get_event)' },
|
||||
order: {
|
||||
type: 'json',
|
||||
description: 'Order object with _dollars and _fp fields (get_order, create_order, etc.)',
|
||||
},
|
||||
series: { type: 'json', description: 'Series object (get_series_by_ticker)' },
|
||||
// Account operations
|
||||
balance: { type: 'number', description: 'Account balance in cents (get_balance)' },
|
||||
portfolio_value: { type: 'number', description: 'Portfolio value in cents (get_balance)' },
|
||||
updated_ts: { type: 'number', description: 'Unix timestamp of last update (get_balance)' },
|
||||
// Orderbook (V2 uses tuple arrays)
|
||||
orderbook: {
|
||||
type: 'json',
|
||||
description: 'Orderbook with yes/no/yes_dollars/no_dollars tuple arrays',
|
||||
},
|
||||
orderbook_fp: {
|
||||
type: 'json',
|
||||
description: 'Fixed-point orderbook with yes_dollars/no_dollars tuple arrays',
|
||||
},
|
||||
// Exchange status
|
||||
exchange_status: {
|
||||
type: 'string',
|
||||
description: 'Exchange status string (get_exchange_status)',
|
||||
},
|
||||
trading_active: { type: 'boolean', description: 'Trading active flag (get_exchange_status)' },
|
||||
// Cancel order specific
|
||||
reduced_by: { type: 'number', description: 'Number of contracts reduced (cancel_order)' },
|
||||
reduced_by_fp: {
|
||||
type: 'string',
|
||||
description: 'Contracts reduced in fixed-point (cancel_order)',
|
||||
},
|
||||
// Candlesticks ticker
|
||||
ticker: { type: 'string', description: 'Market ticker (get_candlesticks)' },
|
||||
// Pagination (flat cursor instead of nested paging object)
|
||||
cursor: { type: 'string', description: 'Pagination cursor for fetching more results' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ export const PolymarketBlock: BlockConfig = {
|
||||
name: 'Polymarket',
|
||||
description: 'Access prediction markets data from Polymarket',
|
||||
longDescription:
|
||||
'Integrate Polymarket prediction markets into the workflow. Can get markets, market, events, event, tags, series, orderbook, price, midpoint, price history, last trade price, spread, tick size, positions, trades, and search.',
|
||||
'Integrate Polymarket prediction markets into the workflow. Can get markets, market, events, event, tags, series, orderbook, price, midpoint, price history, last trade price, spread, tick size, positions, trades, activity, leaderboard, holders, and search.',
|
||||
docsLink: 'https://docs.sim.ai/tools/polymarket',
|
||||
category: 'tools',
|
||||
bgColor: '#4C82FB',
|
||||
@@ -34,6 +34,9 @@ export const PolymarketBlock: BlockConfig = {
|
||||
{ label: 'Get Tick Size', id: 'get_tick_size' },
|
||||
{ label: 'Get Positions', id: 'get_positions' },
|
||||
{ label: 'Get Trades', id: 'get_trades' },
|
||||
{ label: 'Get Activity', id: 'get_activity' },
|
||||
{ label: 'Get Leaderboard', id: 'get_leaderboard' },
|
||||
{ label: 'Get Market Holders', id: 'get_holders' },
|
||||
],
|
||||
value: () => 'get_markets',
|
||||
},
|
||||
@@ -101,14 +104,281 @@ export const PolymarketBlock: BlockConfig = {
|
||||
placeholder: 'Wallet address (optional filter)',
|
||||
condition: { field: 'operation', value: ['get_trades'] },
|
||||
},
|
||||
// Market filter for positions and trades
|
||||
// Market/Event filter for positions and trades
|
||||
{
|
||||
id: 'market',
|
||||
title: 'Market ID',
|
||||
title: 'Condition ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Market ID (optional filter)',
|
||||
placeholder: 'Condition ID filter (comma-separated)',
|
||||
condition: { field: 'operation', value: ['get_positions', 'get_trades'] },
|
||||
},
|
||||
{
|
||||
id: 'positionEventId',
|
||||
title: 'Event ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Event ID filter (alternative to Condition ID)',
|
||||
condition: { field: 'operation', value: ['get_positions', 'get_trades'] },
|
||||
},
|
||||
// Positions-specific filters
|
||||
{
|
||||
id: 'sizeThreshold',
|
||||
title: 'Size Threshold',
|
||||
type: 'short-input',
|
||||
placeholder: 'Minimum position size (default: 1)',
|
||||
condition: { field: 'operation', value: ['get_positions'] },
|
||||
},
|
||||
{
|
||||
id: 'redeemable',
|
||||
title: 'Redeemable',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'All', id: '' },
|
||||
{ label: 'Redeemable Only', id: 'true' },
|
||||
{ label: 'Non-Redeemable Only', id: 'false' },
|
||||
],
|
||||
condition: { field: 'operation', value: ['get_positions'] },
|
||||
},
|
||||
{
|
||||
id: 'mergeable',
|
||||
title: 'Mergeable',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'All', id: '' },
|
||||
{ label: 'Mergeable Only', id: 'true' },
|
||||
{ label: 'Non-Mergeable Only', id: 'false' },
|
||||
],
|
||||
condition: { field: 'operation', value: ['get_positions'] },
|
||||
},
|
||||
{
|
||||
id: 'positionSortBy',
|
||||
title: 'Sort By',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'Default', id: '' },
|
||||
{ label: 'Tokens', id: 'TOKENS' },
|
||||
{ label: 'Current Value', id: 'CURRENT' },
|
||||
{ label: 'Initial Value', id: 'INITIAL' },
|
||||
{ label: 'Cash P&L', id: 'CASHPNL' },
|
||||
{ label: 'Percent P&L', id: 'PERCENTPNL' },
|
||||
{ label: 'Title', id: 'TITLE' },
|
||||
{ label: 'Price', id: 'PRICE' },
|
||||
{ label: 'Avg Price', id: 'AVGPRICE' },
|
||||
],
|
||||
condition: { field: 'operation', value: ['get_positions'] },
|
||||
},
|
||||
{
|
||||
id: 'positionSortDirection',
|
||||
title: 'Sort Direction',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'Descending', id: 'DESC' },
|
||||
{ label: 'Ascending', id: 'ASC' },
|
||||
],
|
||||
condition: { field: 'operation', value: ['get_positions'] },
|
||||
},
|
||||
{
|
||||
id: 'positionTitle',
|
||||
title: 'Title Filter',
|
||||
type: 'short-input',
|
||||
placeholder: 'Search by title',
|
||||
condition: { field: 'operation', value: ['get_positions'] },
|
||||
},
|
||||
// Trades-specific filters
|
||||
{
|
||||
id: 'tradeSide',
|
||||
title: 'Trade Side',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'All', id: '' },
|
||||
{ label: 'Buy', id: 'BUY' },
|
||||
{ label: 'Sell', id: 'SELL' },
|
||||
],
|
||||
condition: { field: 'operation', value: ['get_trades'] },
|
||||
},
|
||||
{
|
||||
id: 'takerOnly',
|
||||
title: 'Taker Only',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'Yes (default)', id: 'true' },
|
||||
{ label: 'No', id: 'false' },
|
||||
],
|
||||
condition: { field: 'operation', value: ['get_trades'] },
|
||||
},
|
||||
{
|
||||
id: 'filterType',
|
||||
title: 'Filter Type',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'None', id: '' },
|
||||
{ label: 'Cash', id: 'CASH' },
|
||||
{ label: 'Tokens', id: 'TOKENS' },
|
||||
],
|
||||
condition: { field: 'operation', value: ['get_trades'] },
|
||||
},
|
||||
{
|
||||
id: 'filterAmount',
|
||||
title: 'Filter Amount',
|
||||
type: 'short-input',
|
||||
placeholder: 'Minimum amount threshold',
|
||||
condition: { field: 'operation', value: ['get_trades'] },
|
||||
},
|
||||
// Activity-specific fields
|
||||
{
|
||||
id: 'activityUser',
|
||||
title: 'User Wallet Address',
|
||||
type: 'short-input',
|
||||
placeholder: 'Wallet address (0x-prefixed)',
|
||||
required: true,
|
||||
condition: { field: 'operation', value: ['get_activity'] },
|
||||
},
|
||||
{
|
||||
id: 'activityType',
|
||||
title: 'Activity Type',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'All', id: '' },
|
||||
{ label: 'Trade', id: 'TRADE' },
|
||||
{ label: 'Split', id: 'SPLIT' },
|
||||
{ label: 'Merge', id: 'MERGE' },
|
||||
{ label: 'Redeem', id: 'REDEEM' },
|
||||
{ label: 'Reward', id: 'REWARD' },
|
||||
{ label: 'Conversion', id: 'CONVERSION' },
|
||||
{ label: 'Maker Rebate', id: 'MAKER_REBATE' },
|
||||
],
|
||||
condition: { field: 'operation', value: ['get_activity'] },
|
||||
},
|
||||
{
|
||||
id: 'activityMarket',
|
||||
title: 'Condition ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Condition ID filter (comma-separated)',
|
||||
condition: { field: 'operation', value: ['get_activity'] },
|
||||
},
|
||||
{
|
||||
id: 'activityEventId',
|
||||
title: 'Event ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Event ID filter (comma-separated)',
|
||||
condition: { field: 'operation', value: ['get_activity'] },
|
||||
},
|
||||
{
|
||||
id: 'activitySide',
|
||||
title: 'Trade Side',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'All', id: '' },
|
||||
{ label: 'Buy', id: 'BUY' },
|
||||
{ label: 'Sell', id: 'SELL' },
|
||||
],
|
||||
condition: { field: 'operation', value: ['get_activity'] },
|
||||
},
|
||||
{
|
||||
id: 'activitySortBy',
|
||||
title: 'Sort By',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'Timestamp', id: 'TIMESTAMP' },
|
||||
{ label: 'Tokens', id: 'TOKENS' },
|
||||
{ label: 'Cash', id: 'CASH' },
|
||||
],
|
||||
condition: { field: 'operation', value: ['get_activity'] },
|
||||
},
|
||||
{
|
||||
id: 'activitySortDirection',
|
||||
title: 'Sort Direction',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'Descending', id: 'DESC' },
|
||||
{ label: 'Ascending', id: 'ASC' },
|
||||
],
|
||||
condition: { field: 'operation', value: ['get_activity'] },
|
||||
},
|
||||
{
|
||||
id: 'activityStart',
|
||||
title: 'Start Timestamp',
|
||||
type: 'short-input',
|
||||
placeholder: 'Unix timestamp (seconds)',
|
||||
condition: { field: 'operation', value: ['get_activity'] },
|
||||
},
|
||||
{
|
||||
id: 'activityEnd',
|
||||
title: 'End Timestamp',
|
||||
type: 'short-input',
|
||||
placeholder: 'Unix timestamp (seconds)',
|
||||
condition: { field: 'operation', value: ['get_activity'] },
|
||||
},
|
||||
// Leaderboard-specific fields
|
||||
{
|
||||
id: 'leaderboardCategory',
|
||||
title: 'Category',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'Overall', id: 'OVERALL' },
|
||||
{ label: 'Politics', id: 'POLITICS' },
|
||||
{ label: 'Sports', id: 'SPORTS' },
|
||||
{ label: 'Crypto', id: 'CRYPTO' },
|
||||
{ label: 'Culture', id: 'CULTURE' },
|
||||
{ label: 'Mentions', id: 'MENTIONS' },
|
||||
{ label: 'Weather', id: 'WEATHER' },
|
||||
{ label: 'Economics', id: 'ECONOMICS' },
|
||||
{ label: 'Tech', id: 'TECH' },
|
||||
{ label: 'Finance', id: 'FINANCE' },
|
||||
],
|
||||
condition: { field: 'operation', value: ['get_leaderboard'] },
|
||||
},
|
||||
{
|
||||
id: 'leaderboardTimePeriod',
|
||||
title: 'Time Period',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'Day', id: 'DAY' },
|
||||
{ label: 'Week', id: 'WEEK' },
|
||||
{ label: 'Month', id: 'MONTH' },
|
||||
{ label: 'All Time', id: 'ALL' },
|
||||
],
|
||||
condition: { field: 'operation', value: ['get_leaderboard'] },
|
||||
},
|
||||
{
|
||||
id: 'leaderboardOrderBy',
|
||||
title: 'Order By',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'Profit/Loss', id: 'PNL' },
|
||||
{ label: 'Volume', id: 'VOL' },
|
||||
],
|
||||
condition: { field: 'operation', value: ['get_leaderboard'] },
|
||||
},
|
||||
{
|
||||
id: 'leaderboardUser',
|
||||
title: 'User Address',
|
||||
type: 'short-input',
|
||||
placeholder: 'Filter by specific user wallet',
|
||||
condition: { field: 'operation', value: ['get_leaderboard'] },
|
||||
},
|
||||
{
|
||||
id: 'leaderboardUserName',
|
||||
title: 'Username',
|
||||
type: 'short-input',
|
||||
placeholder: 'Filter by username',
|
||||
condition: { field: 'operation', value: ['get_leaderboard'] },
|
||||
},
|
||||
// Market Holders-specific fields
|
||||
{
|
||||
id: 'holdersMarket',
|
||||
title: 'Condition ID',
|
||||
type: 'short-input',
|
||||
placeholder: 'Condition ID (comma-separated)',
|
||||
required: true,
|
||||
condition: { field: 'operation', value: ['get_holders'] },
|
||||
},
|
||||
{
|
||||
id: 'holdersMinBalance',
|
||||
title: 'Min Balance',
|
||||
type: 'short-input',
|
||||
placeholder: 'Minimum balance threshold (default: 1)',
|
||||
condition: { field: 'operation', value: ['get_holders'] },
|
||||
},
|
||||
// Token ID for CLOB operations
|
||||
{
|
||||
id: 'tokenId',
|
||||
@@ -205,11 +475,11 @@ Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extr
|
||||
// Filters for list operations
|
||||
{
|
||||
id: 'closed',
|
||||
title: 'Status',
|
||||
title: 'Closed Status',
|
||||
type: 'dropdown',
|
||||
options: [
|
||||
{ label: 'All', id: '' },
|
||||
{ label: 'Active Only', id: 'false' },
|
||||
{ label: 'Open Only', id: 'false' },
|
||||
{ label: 'Closed Only', id: 'true' },
|
||||
],
|
||||
condition: { field: 'operation', value: ['get_markets', 'get_events'] },
|
||||
@@ -269,7 +539,18 @@ Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extr
|
||||
placeholder: 'Number of results (max 50)',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: ['get_markets', 'get_events', 'get_tags', 'search', 'get_series', 'get_trades'],
|
||||
value: [
|
||||
'get_markets',
|
||||
'get_events',
|
||||
'get_tags',
|
||||
'search',
|
||||
'get_series',
|
||||
'get_trades',
|
||||
'get_positions',
|
||||
'get_activity',
|
||||
'get_leaderboard',
|
||||
'get_holders',
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -279,9 +560,25 @@ Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extr
|
||||
placeholder: 'Pagination offset',
|
||||
condition: {
|
||||
field: 'operation',
|
||||
value: ['get_markets', 'get_events', 'get_tags', 'search', 'get_series', 'get_trades'],
|
||||
value: [
|
||||
'get_markets',
|
||||
'get_events',
|
||||
'get_tags',
|
||||
'get_series',
|
||||
'get_trades',
|
||||
'get_positions',
|
||||
'get_activity',
|
||||
'get_leaderboard',
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'page',
|
||||
title: 'Page',
|
||||
type: 'short-input',
|
||||
placeholder: 'Page number (1-indexed)',
|
||||
condition: { field: 'operation', value: ['search'] },
|
||||
},
|
||||
],
|
||||
tools: {
|
||||
access: [
|
||||
@@ -302,6 +599,9 @@ Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extr
|
||||
'polymarket_get_tick_size',
|
||||
'polymarket_get_positions',
|
||||
'polymarket_get_trades',
|
||||
'polymarket_get_activity',
|
||||
'polymarket_get_leaderboard',
|
||||
'polymarket_get_holders',
|
||||
],
|
||||
config: {
|
||||
tool: (params) => {
|
||||
@@ -340,12 +640,49 @@ Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extr
|
||||
return 'polymarket_get_positions'
|
||||
case 'get_trades':
|
||||
return 'polymarket_get_trades'
|
||||
case 'get_activity':
|
||||
return 'polymarket_get_activity'
|
||||
case 'get_leaderboard':
|
||||
return 'polymarket_get_leaderboard'
|
||||
case 'get_holders':
|
||||
return 'polymarket_get_holders'
|
||||
default:
|
||||
return 'polymarket_get_markets'
|
||||
}
|
||||
},
|
||||
params: (params) => {
|
||||
const { operation, marketSlug, eventSlug, orderEvents, order, ...rest } = params
|
||||
const {
|
||||
operation,
|
||||
marketSlug,
|
||||
eventSlug,
|
||||
orderEvents,
|
||||
order,
|
||||
positionEventId,
|
||||
tradeSide,
|
||||
positionSortBy,
|
||||
positionSortDirection,
|
||||
positionTitle,
|
||||
// Activity params
|
||||
activityUser,
|
||||
activityType,
|
||||
activityMarket,
|
||||
activityEventId,
|
||||
activitySide,
|
||||
activitySortBy,
|
||||
activitySortDirection,
|
||||
activityStart,
|
||||
activityEnd,
|
||||
// Leaderboard params
|
||||
leaderboardCategory,
|
||||
leaderboardTimePeriod,
|
||||
leaderboardOrderBy,
|
||||
leaderboardUser,
|
||||
leaderboardUserName,
|
||||
// Holders params
|
||||
holdersMarket,
|
||||
holdersMinBalance,
|
||||
...rest
|
||||
} = params
|
||||
const cleanParams: Record<string, any> = {}
|
||||
|
||||
// Map marketSlug to slug for get_market
|
||||
@@ -365,6 +702,51 @@ Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extr
|
||||
cleanParams.order = orderEvents
|
||||
}
|
||||
|
||||
// Map positionEventId to eventId for positions and trades
|
||||
if ((operation === 'get_positions' || operation === 'get_trades') && positionEventId) {
|
||||
cleanParams.eventId = positionEventId
|
||||
}
|
||||
|
||||
// Map tradeSide to side for trades
|
||||
if (operation === 'get_trades' && tradeSide) {
|
||||
cleanParams.side = tradeSide
|
||||
}
|
||||
|
||||
// Map position-specific fields
|
||||
if (operation === 'get_positions') {
|
||||
if (positionSortBy) cleanParams.sortBy = positionSortBy
|
||||
if (positionSortDirection) cleanParams.sortDirection = positionSortDirection
|
||||
if (positionTitle) cleanParams.title = positionTitle
|
||||
}
|
||||
|
||||
// Map activity-specific fields
|
||||
if (operation === 'get_activity') {
|
||||
if (activityUser) cleanParams.user = activityUser
|
||||
if (activityType) cleanParams.type = activityType
|
||||
if (activityMarket) cleanParams.market = activityMarket
|
||||
if (activityEventId) cleanParams.eventId = activityEventId
|
||||
if (activitySide) cleanParams.side = activitySide
|
||||
if (activitySortBy) cleanParams.sortBy = activitySortBy
|
||||
if (activitySortDirection) cleanParams.sortDirection = activitySortDirection
|
||||
if (activityStart) cleanParams.start = Number(activityStart)
|
||||
if (activityEnd) cleanParams.end = Number(activityEnd)
|
||||
}
|
||||
|
||||
// Map leaderboard-specific fields
|
||||
if (operation === 'get_leaderboard') {
|
||||
if (leaderboardCategory) cleanParams.category = leaderboardCategory
|
||||
if (leaderboardTimePeriod) cleanParams.timePeriod = leaderboardTimePeriod
|
||||
if (leaderboardOrderBy) cleanParams.orderBy = leaderboardOrderBy
|
||||
if (leaderboardUser) cleanParams.user = leaderboardUser
|
||||
if (leaderboardUserName) cleanParams.userName = leaderboardUserName
|
||||
}
|
||||
|
||||
// Map holders-specific fields
|
||||
if (operation === 'get_holders') {
|
||||
if (holdersMarket) cleanParams.market = holdersMarket
|
||||
if (holdersMinBalance) cleanParams.minBalance = holdersMinBalance
|
||||
}
|
||||
|
||||
// Convert numeric fields from string to number for get_price_history
|
||||
if (operation === 'get_price_history') {
|
||||
if (rest.fidelity) cleanParams.fidelity = Number(rest.fidelity)
|
||||
@@ -394,13 +776,55 @@ Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extr
|
||||
seriesId: { type: 'string', description: 'Series ID' },
|
||||
query: { type: 'string', description: 'Search query' },
|
||||
user: { type: 'string', description: 'User wallet address' },
|
||||
market: { type: 'string', description: 'Market ID filter' },
|
||||
market: { type: 'string', description: 'Condition ID filter' },
|
||||
positionEventId: { type: 'string', description: 'Event ID filter for positions/trades' },
|
||||
tokenId: { type: 'string', description: 'CLOB Token ID' },
|
||||
side: { type: 'string', description: 'Order side (buy/sell)' },
|
||||
interval: { type: 'string', description: 'Price history interval' },
|
||||
fidelity: { type: 'number', description: 'Data resolution in minutes' },
|
||||
startTs: { type: 'number', description: 'Start timestamp (Unix)' },
|
||||
endTs: { type: 'number', description: 'End timestamp (Unix)' },
|
||||
// Positions-specific inputs
|
||||
sizeThreshold: { type: 'string', description: 'Minimum position size threshold' },
|
||||
redeemable: { type: 'string', description: 'Filter by redeemable status' },
|
||||
mergeable: { type: 'string', description: 'Filter by mergeable status' },
|
||||
positionSortBy: { type: 'string', description: 'Sort positions by field' },
|
||||
positionSortDirection: { type: 'string', description: 'Sort direction (ASC/DESC)' },
|
||||
positionTitle: { type: 'string', description: 'Filter positions by title' },
|
||||
// Trades-specific inputs
|
||||
tradeSide: { type: 'string', description: 'Filter trades by side (BUY/SELL)' },
|
||||
takerOnly: { type: 'string', description: 'Filter to taker trades only' },
|
||||
filterType: { type: 'string', description: 'Trade filter type (CASH/TOKENS)' },
|
||||
filterAmount: { type: 'string', description: 'Minimum trade amount threshold' },
|
||||
// List operation filters
|
||||
closed: { type: 'string', description: 'Filter by closed status' },
|
||||
order: { type: 'string', description: 'Sort field for markets' },
|
||||
orderEvents: { type: 'string', description: 'Sort field for events' },
|
||||
ascending: { type: 'string', description: 'Sort order (true/false)' },
|
||||
tagId: { type: 'string', description: 'Filter by tag ID' },
|
||||
// Pagination
|
||||
limit: { type: 'string', description: 'Number of results per page' },
|
||||
offset: { type: 'string', description: 'Pagination offset' },
|
||||
page: { type: 'string', description: 'Page number for search' },
|
||||
// Activity-specific inputs
|
||||
activityUser: { type: 'string', description: 'User wallet address for activity' },
|
||||
activityType: { type: 'string', description: 'Activity type filter' },
|
||||
activityMarket: { type: 'string', description: 'Condition ID filter for activity' },
|
||||
activityEventId: { type: 'string', description: 'Event ID filter for activity' },
|
||||
activitySide: { type: 'string', description: 'Trade side filter for activity' },
|
||||
activitySortBy: { type: 'string', description: 'Sort field for activity' },
|
||||
activitySortDirection: { type: 'string', description: 'Sort direction for activity' },
|
||||
activityStart: { type: 'string', description: 'Start timestamp for activity' },
|
||||
activityEnd: { type: 'string', description: 'End timestamp for activity' },
|
||||
// Leaderboard-specific inputs
|
||||
leaderboardCategory: { type: 'string', description: 'Leaderboard category' },
|
||||
leaderboardTimePeriod: { type: 'string', description: 'Leaderboard time period' },
|
||||
leaderboardOrderBy: { type: 'string', description: 'Leaderboard order by field' },
|
||||
leaderboardUser: { type: 'string', description: 'Filter leaderboard by user' },
|
||||
leaderboardUserName: { type: 'string', description: 'Filter leaderboard by username' },
|
||||
// Holders-specific inputs
|
||||
holdersMarket: { type: 'string', description: 'Condition ID for holders lookup' },
|
||||
holdersMinBalance: { type: 'string', description: 'Minimum balance threshold' },
|
||||
},
|
||||
outputs: {
|
||||
// List operations
|
||||
@@ -422,11 +846,19 @@ Return ONLY the Unix timestamp as a number - no explanations, no quotes, no extr
|
||||
description: 'Search results with markets, events, profiles (search)',
|
||||
},
|
||||
// CLOB operations
|
||||
orderbook: { type: 'json', description: 'Order book with bids and asks (get_orderbook)' },
|
||||
orderbook: {
|
||||
type: 'json',
|
||||
description: 'Order book with bids and asks (get_orderbook)',
|
||||
},
|
||||
price: { type: 'string', description: 'Market price (get_price, get_last_trade_price)' },
|
||||
side: { type: 'string', description: 'Last trade side - BUY or SELL (get_last_trade_price)' },
|
||||
midpoint: { type: 'string', description: 'Midpoint price (get_midpoint)' },
|
||||
history: { type: 'json', description: 'Price history entries (get_price_history)' },
|
||||
spread: { type: 'json', description: 'Bid-ask spread (get_spread)' },
|
||||
spread: { type: 'json', description: 'Spread value object (get_spread)' },
|
||||
tickSize: { type: 'string', description: 'Minimum tick size (get_tick_size)' },
|
||||
// Data API operations
|
||||
activity: { type: 'json', description: 'Array of user activity entries (get_activity)' },
|
||||
leaderboard: { type: 'json', description: 'Array of leaderboard entries (get_leaderboard)' },
|
||||
holders: { type: 'json', description: 'Array of market holder groups (get_holders)' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ import { IntercomBlock, IntercomV2Block } from '@/blocks/blocks/intercom'
|
||||
import { JinaBlock } from '@/blocks/blocks/jina'
|
||||
import { JiraBlock } from '@/blocks/blocks/jira'
|
||||
import { JiraServiceManagementBlock } from '@/blocks/blocks/jira_service_management'
|
||||
import { KalshiBlock } from '@/blocks/blocks/kalshi'
|
||||
import { KalshiBlock, KalshiV2Block } from '@/blocks/blocks/kalshi'
|
||||
import { KnowledgeBlock } from '@/blocks/blocks/knowledge'
|
||||
import { LangsmithBlock } from '@/blocks/blocks/langsmith'
|
||||
import { LemlistBlock } from '@/blocks/blocks/lemlist'
|
||||
@@ -222,6 +222,7 @@ export const registry: Record<string, BlockConfig> = {
|
||||
jira: JiraBlock,
|
||||
jira_service_management: JiraServiceManagementBlock,
|
||||
kalshi: KalshiBlock,
|
||||
kalshi_v2: KalshiV2Block,
|
||||
knowledge: KnowledgeBlock,
|
||||
langsmith: LangsmithBlock,
|
||||
lemlist: LemlistBlock,
|
||||
|
||||
146
apps/sim/tools/intercom/assign_conversation.ts
Normal file
146
apps/sim/tools/intercom/assign_conversation.ts
Normal 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 },
|
||||
},
|
||||
}
|
||||
115
apps/sim/tools/intercom/attach_contact_to_company.ts
Normal file
115
apps/sim/tools/intercom/attach_contact_to_company.ts
Normal 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 },
|
||||
},
|
||||
}
|
||||
129
apps/sim/tools/intercom/close_conversation.ts
Normal file
129
apps/sim/tools/intercom/close_conversation.ts
Normal 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)' },
|
||||
},
|
||||
}
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
148
apps/sim/tools/intercom/create_event.ts
Normal file
148
apps/sim/tools/intercom/create_event.ts
Normal 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)',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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: {
|
||||
|
||||
131
apps/sim/tools/intercom/create_note.ts
Normal file
131
apps/sim/tools/intercom/create_note.ts
Normal 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' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
97
apps/sim/tools/intercom/create_tag.ts
Normal file
97
apps/sim/tools/intercom/create_tag.ts
Normal 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)' },
|
||||
},
|
||||
}
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
101
apps/sim/tools/intercom/detach_contact_from_company.ts
Normal file
101
apps/sim/tools/intercom/detach_contact_from_company.ts
Normal 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 },
|
||||
},
|
||||
}
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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'
|
||||
|
||||
125
apps/sim/tools/intercom/list_admins.ts
Normal file
125
apps/sim/tools/intercom/list_admins.ts
Normal 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)' },
|
||||
},
|
||||
}
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
86
apps/sim/tools/intercom/list_tags.ts
Normal file
86
apps/sim/tools/intercom/list_tags.ts
Normal 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)' },
|
||||
},
|
||||
}
|
||||
114
apps/sim/tools/intercom/open_conversation.ts
Normal file
114
apps/sim/tools/intercom/open_conversation.ts
Normal 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)' },
|
||||
},
|
||||
}
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
124
apps/sim/tools/intercom/snooze_conversation.ts
Normal file
124
apps/sim/tools/intercom/snooze_conversation.ts
Normal 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,
|
||||
},
|
||||
},
|
||||
}
|
||||
89
apps/sim/tools/intercom/tag_contact.ts
Normal file
89
apps/sim/tools/intercom/tag_contact.ts
Normal 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)' },
|
||||
},
|
||||
}
|
||||
97
apps/sim/tools/intercom/tag_conversation.ts
Normal file
97
apps/sim/tools/intercom/tag_conversation.ts
Normal 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)' },
|
||||
},
|
||||
}
|
||||
@@ -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 })
|
||||
|
||||
|
||||
87
apps/sim/tools/intercom/untag_contact.ts
Normal file
87
apps/sim/tools/intercom/untag_contact.ts
Normal 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)' },
|
||||
},
|
||||
}
|
||||
@@ -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: {
|
||||
|
||||
193
apps/sim/tools/intercom/update_ticket.ts
Normal file
193
apps/sim/tools/intercom/update_ticket.ts
Normal 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' },
|
||||
},
|
||||
}
|
||||
@@ -158,3 +158,300 @@ export const kalshiAmendOrderTool: ToolConfig<KalshiAmendOrderParams, KalshiAmen
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export interface KalshiAmendOrderV2Params extends KalshiAuthParams {
|
||||
orderId: string // Order ID to amend (required)
|
||||
ticker: string // Market ticker (required)
|
||||
side: string // 'yes' or 'no' (required)
|
||||
action: string // 'buy' or 'sell' (required)
|
||||
clientOrderId?: string // Original client order ID (optional in V2)
|
||||
updatedClientOrderId?: string // New client order ID (optional in V2)
|
||||
count?: string // Updated quantity
|
||||
yesPrice?: string // Updated yes price in cents (1-99)
|
||||
noPrice?: string // Updated no price in cents (1-99)
|
||||
yesPriceDollars?: string // Updated yes price in dollars
|
||||
noPriceDollars?: string // Updated no price in dollars
|
||||
countFp?: string // Count in fixed-point for fractional contracts
|
||||
}
|
||||
|
||||
export interface KalshiAmendOrderV2Order {
|
||||
order_id: string
|
||||
user_id: string | null
|
||||
ticker: string
|
||||
event_ticker: string
|
||||
status: string
|
||||
side: string
|
||||
type: string
|
||||
yes_price: number | null
|
||||
no_price: number | null
|
||||
action: string
|
||||
count: number
|
||||
remaining_count: number
|
||||
created_time: string
|
||||
expiration_time: string | null
|
||||
order_group_id: string | null
|
||||
client_order_id: string | null
|
||||
place_count: number | null
|
||||
decrease_count: number | null
|
||||
queue_position: number | null
|
||||
maker_fill_count: number | null
|
||||
taker_fill_count: number | null
|
||||
maker_fees: number | null
|
||||
taker_fees: number | null
|
||||
last_update_time: string | null
|
||||
take_profit_order_id: string | null
|
||||
stop_loss_order_id: string | null
|
||||
amend_count: number | null
|
||||
amend_taker_fill_count: number | null
|
||||
}
|
||||
|
||||
export interface KalshiAmendOrderV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
old_order: KalshiAmendOrderV2Order
|
||||
order: KalshiAmendOrderV2Order
|
||||
}
|
||||
}
|
||||
|
||||
export const kalshiAmendOrderV2Tool: ToolConfig<
|
||||
KalshiAmendOrderV2Params,
|
||||
KalshiAmendOrderV2Response
|
||||
> = {
|
||||
id: 'kalshi_amend_order_v2',
|
||||
name: 'Amend Order on Kalshi V2',
|
||||
description:
|
||||
'Modify the price or quantity of an existing order on Kalshi (V2 with full API response)',
|
||||
version: '2.0.0',
|
||||
|
||||
params: {
|
||||
keyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your Kalshi API Key ID',
|
||||
},
|
||||
privateKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your RSA Private Key (PEM format)',
|
||||
},
|
||||
orderId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The order ID to amend',
|
||||
},
|
||||
ticker: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Market ticker',
|
||||
},
|
||||
side: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: "Side of the order: 'yes' or 'no'",
|
||||
},
|
||||
action: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: "Action type: 'buy' or 'sell'",
|
||||
},
|
||||
clientOrderId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The original client-specified order ID',
|
||||
},
|
||||
updatedClientOrderId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The new client-specified order ID after amendment',
|
||||
},
|
||||
count: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated quantity for the order',
|
||||
},
|
||||
yesPrice: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated yes price in cents (1-99)',
|
||||
},
|
||||
noPrice: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated no price in cents (1-99)',
|
||||
},
|
||||
yesPriceDollars: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated yes price in dollars (e.g., "0.56")',
|
||||
},
|
||||
noPriceDollars: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Updated no price in dollars (e.g., "0.56")',
|
||||
},
|
||||
countFp: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Count in fixed-point for fractional contracts',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => buildKalshiUrl(`/portfolio/orders/${params.orderId}/amend`),
|
||||
method: 'POST',
|
||||
headers: (params) => {
|
||||
const path = `/trade-api/v2/portfolio/orders/${params.orderId}/amend`
|
||||
return buildKalshiAuthHeaders(params.keyId, params.privateKey, 'POST', path)
|
||||
},
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {
|
||||
ticker: params.ticker,
|
||||
side: params.side.toLowerCase(),
|
||||
action: params.action.toLowerCase(),
|
||||
}
|
||||
|
||||
if (params.clientOrderId) body.client_order_id = params.clientOrderId
|
||||
if (params.updatedClientOrderId) body.updated_client_order_id = params.updatedClientOrderId
|
||||
if (params.count) body.count = Number.parseInt(params.count, 10)
|
||||
if (params.yesPrice) body.yes_price = Number.parseInt(params.yesPrice, 10)
|
||||
if (params.noPrice) body.no_price = Number.parseInt(params.noPrice, 10)
|
||||
if (params.yesPriceDollars) body.yes_price_dollars = params.yesPriceDollars
|
||||
if (params.noPriceDollars) body.no_price_dollars = params.noPriceDollars
|
||||
if (params.countFp) body.count_fp = params.countFp
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handleKalshiError(data, response.status, 'amend_order_v2')
|
||||
}
|
||||
|
||||
const mapOrder = (order: any): KalshiAmendOrderV2Order => ({
|
||||
order_id: order.order_id ?? null,
|
||||
user_id: order.user_id ?? null,
|
||||
ticker: order.ticker ?? null,
|
||||
event_ticker: order.event_ticker ?? null,
|
||||
status: order.status ?? null,
|
||||
side: order.side ?? null,
|
||||
type: order.type ?? null,
|
||||
yes_price: order.yes_price ?? null,
|
||||
no_price: order.no_price ?? null,
|
||||
action: order.action ?? null,
|
||||
count: order.count ?? null,
|
||||
remaining_count: order.remaining_count ?? null,
|
||||
created_time: order.created_time ?? null,
|
||||
expiration_time: order.expiration_time ?? null,
|
||||
order_group_id: order.order_group_id ?? null,
|
||||
client_order_id: order.client_order_id ?? null,
|
||||
place_count: order.place_count ?? null,
|
||||
decrease_count: order.decrease_count ?? null,
|
||||
queue_position: order.queue_position ?? null,
|
||||
maker_fill_count: order.maker_fill_count ?? null,
|
||||
taker_fill_count: order.taker_fill_count ?? null,
|
||||
maker_fees: order.maker_fees ?? null,
|
||||
taker_fees: order.taker_fees ?? null,
|
||||
last_update_time: order.last_update_time ?? null,
|
||||
take_profit_order_id: order.take_profit_order_id ?? null,
|
||||
stop_loss_order_id: order.stop_loss_order_id ?? null,
|
||||
amend_count: order.amend_count ?? null,
|
||||
amend_taker_fill_count: order.amend_taker_fill_count ?? null,
|
||||
})
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
old_order: mapOrder(data.old_order || {}),
|
||||
order: mapOrder(data.order || {}),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
old_order: {
|
||||
type: 'object',
|
||||
description: 'The original order object before amendment',
|
||||
properties: {
|
||||
order_id: { type: 'string', description: 'Order ID' },
|
||||
user_id: { type: 'string', description: 'User ID' },
|
||||
ticker: { type: 'string', description: 'Market ticker' },
|
||||
event_ticker: { type: 'string', description: 'Event ticker' },
|
||||
status: { type: 'string', description: 'Order status' },
|
||||
side: { type: 'string', description: 'Order side (yes/no)' },
|
||||
type: { type: 'string', description: 'Order type (limit/market)' },
|
||||
yes_price: { type: 'number', description: 'Yes price in cents' },
|
||||
no_price: { type: 'number', description: 'No price in cents' },
|
||||
action: { type: 'string', description: 'Action (buy/sell)' },
|
||||
count: { type: 'number', description: 'Number of contracts' },
|
||||
remaining_count: { type: 'number', description: 'Remaining contracts' },
|
||||
created_time: { type: 'string', description: 'Order creation time' },
|
||||
expiration_time: { type: 'string', description: 'Order expiration time' },
|
||||
order_group_id: { type: 'string', description: 'Order group ID' },
|
||||
client_order_id: { type: 'string', description: 'Client order ID' },
|
||||
place_count: { type: 'number', description: 'Place count' },
|
||||
decrease_count: { type: 'number', description: 'Decrease count' },
|
||||
queue_position: { type: 'number', description: 'Queue position' },
|
||||
maker_fill_count: { type: 'number', description: 'Maker fill count' },
|
||||
taker_fill_count: { type: 'number', description: 'Taker fill count' },
|
||||
maker_fees: { type: 'number', description: 'Maker fees' },
|
||||
taker_fees: { type: 'number', description: 'Taker fees' },
|
||||
last_update_time: { type: 'string', description: 'Last update time' },
|
||||
take_profit_order_id: { type: 'string', description: 'Take profit order ID' },
|
||||
stop_loss_order_id: { type: 'string', description: 'Stop loss order ID' },
|
||||
amend_count: { type: 'number', description: 'Amend count' },
|
||||
amend_taker_fill_count: { type: 'number', description: 'Amend taker fill count' },
|
||||
},
|
||||
},
|
||||
order: {
|
||||
type: 'object',
|
||||
description: 'The amended order object with full API response fields',
|
||||
properties: {
|
||||
order_id: { type: 'string', description: 'Order ID' },
|
||||
user_id: { type: 'string', description: 'User ID' },
|
||||
ticker: { type: 'string', description: 'Market ticker' },
|
||||
event_ticker: { type: 'string', description: 'Event ticker' },
|
||||
status: { type: 'string', description: 'Order status' },
|
||||
side: { type: 'string', description: 'Order side (yes/no)' },
|
||||
type: { type: 'string', description: 'Order type (limit/market)' },
|
||||
yes_price: { type: 'number', description: 'Yes price in cents' },
|
||||
no_price: { type: 'number', description: 'No price in cents' },
|
||||
action: { type: 'string', description: 'Action (buy/sell)' },
|
||||
count: { type: 'number', description: 'Number of contracts' },
|
||||
remaining_count: { type: 'number', description: 'Remaining contracts' },
|
||||
created_time: { type: 'string', description: 'Order creation time' },
|
||||
expiration_time: { type: 'string', description: 'Order expiration time' },
|
||||
order_group_id: { type: 'string', description: 'Order group ID' },
|
||||
client_order_id: { type: 'string', description: 'Client order ID' },
|
||||
place_count: { type: 'number', description: 'Place count' },
|
||||
decrease_count: { type: 'number', description: 'Decrease count' },
|
||||
queue_position: { type: 'number', description: 'Queue position' },
|
||||
maker_fill_count: { type: 'number', description: 'Maker fill count' },
|
||||
taker_fill_count: { type: 'number', description: 'Taker fill count' },
|
||||
maker_fees: { type: 'number', description: 'Maker fees' },
|
||||
taker_fees: { type: 'number', description: 'Taker fees' },
|
||||
last_update_time: { type: 'string', description: 'Last update time' },
|
||||
take_profit_order_id: { type: 'string', description: 'Take profit order ID' },
|
||||
stop_loss_order_id: { type: 'string', description: 'Stop loss order ID' },
|
||||
amend_count: { type: 'number', description: 'Amend count' },
|
||||
amend_taker_fill_count: { type: 'number', description: 'Amend taker fill count' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -78,3 +78,193 @@ export const kalshiCancelOrderTool: ToolConfig<KalshiCancelOrderParams, KalshiCa
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export interface KalshiCancelOrderV2Params extends KalshiAuthParams {
|
||||
orderId: string // Order ID to cancel (required)
|
||||
}
|
||||
|
||||
export interface KalshiCancelOrderV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
order: {
|
||||
order_id: string
|
||||
user_id: string | null
|
||||
client_order_id: string | null
|
||||
ticker: string
|
||||
side: string
|
||||
action: string
|
||||
type: string
|
||||
status: string
|
||||
yes_price: number | null
|
||||
no_price: number | null
|
||||
yes_price_dollars: string | null
|
||||
no_price_dollars: string | null
|
||||
fill_count: number | null
|
||||
fill_count_fp: string | null
|
||||
remaining_count: number | null
|
||||
remaining_count_fp: string | null
|
||||
initial_count: number | null
|
||||
initial_count_fp: string | null
|
||||
taker_fees: number | null
|
||||
maker_fees: number | null
|
||||
taker_fees_dollars: string | null
|
||||
maker_fees_dollars: string | null
|
||||
taker_fill_cost: number | null
|
||||
maker_fill_cost: number | null
|
||||
taker_fill_cost_dollars: string | null
|
||||
maker_fill_cost_dollars: string | null
|
||||
queue_position: number | null
|
||||
expiration_time: string | null
|
||||
created_time: string | null
|
||||
last_update_time: string | null
|
||||
self_trade_prevention_type: string | null
|
||||
order_group_id: string | null
|
||||
cancel_order_on_pause: boolean | null
|
||||
}
|
||||
reduced_by: number
|
||||
reduced_by_fp: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export const kalshiCancelOrderV2Tool: ToolConfig<
|
||||
KalshiCancelOrderV2Params,
|
||||
KalshiCancelOrderV2Response
|
||||
> = {
|
||||
id: 'kalshi_cancel_order_v2',
|
||||
name: 'Cancel Order on Kalshi V2',
|
||||
description: 'Cancel an existing order on Kalshi (V2 with full API response)',
|
||||
version: '2.0.0',
|
||||
|
||||
params: {
|
||||
keyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your Kalshi API Key ID',
|
||||
},
|
||||
privateKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your RSA Private Key (PEM format)',
|
||||
},
|
||||
orderId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The order ID to cancel',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => buildKalshiUrl(`/portfolio/orders/${params.orderId}`),
|
||||
method: 'DELETE',
|
||||
headers: (params) => {
|
||||
const path = `/trade-api/v2/portfolio/orders/${params.orderId}`
|
||||
return buildKalshiAuthHeaders(params.keyId, params.privateKey, 'DELETE', path)
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handleKalshiError(data, response.status, 'cancel_order_v2')
|
||||
}
|
||||
|
||||
const order = data.order || {}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
order: {
|
||||
order_id: order.order_id ?? null,
|
||||
user_id: order.user_id ?? null,
|
||||
client_order_id: order.client_order_id ?? null,
|
||||
ticker: order.ticker ?? null,
|
||||
side: order.side ?? null,
|
||||
action: order.action ?? null,
|
||||
type: order.type ?? null,
|
||||
status: order.status ?? null,
|
||||
yes_price: order.yes_price ?? null,
|
||||
no_price: order.no_price ?? null,
|
||||
yes_price_dollars: order.yes_price_dollars ?? null,
|
||||
no_price_dollars: order.no_price_dollars ?? null,
|
||||
fill_count: order.fill_count ?? null,
|
||||
fill_count_fp: order.fill_count_fp ?? null,
|
||||
remaining_count: order.remaining_count ?? null,
|
||||
remaining_count_fp: order.remaining_count_fp ?? null,
|
||||
initial_count: order.initial_count ?? null,
|
||||
initial_count_fp: order.initial_count_fp ?? null,
|
||||
taker_fees: order.taker_fees ?? null,
|
||||
maker_fees: order.maker_fees ?? null,
|
||||
taker_fees_dollars: order.taker_fees_dollars ?? null,
|
||||
maker_fees_dollars: order.maker_fees_dollars ?? null,
|
||||
taker_fill_cost: order.taker_fill_cost ?? null,
|
||||
maker_fill_cost: order.maker_fill_cost ?? null,
|
||||
taker_fill_cost_dollars: order.taker_fill_cost_dollars ?? null,
|
||||
maker_fill_cost_dollars: order.maker_fill_cost_dollars ?? null,
|
||||
queue_position: order.queue_position ?? null,
|
||||
expiration_time: order.expiration_time ?? null,
|
||||
created_time: order.created_time ?? null,
|
||||
last_update_time: order.last_update_time ?? null,
|
||||
self_trade_prevention_type: order.self_trade_prevention_type ?? null,
|
||||
order_group_id: order.order_group_id ?? null,
|
||||
cancel_order_on_pause: order.cancel_order_on_pause ?? null,
|
||||
},
|
||||
reduced_by: data.reduced_by ?? 0,
|
||||
reduced_by_fp: data.reduced_by_fp ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
order: {
|
||||
type: 'object',
|
||||
description: 'The canceled order object with full API response fields',
|
||||
properties: {
|
||||
order_id: { type: 'string', description: 'Order ID' },
|
||||
user_id: { type: 'string', description: 'User ID' },
|
||||
client_order_id: { type: 'string', description: 'Client order ID' },
|
||||
ticker: { type: 'string', description: 'Market ticker' },
|
||||
side: { type: 'string', description: 'Order side (yes/no)' },
|
||||
action: { type: 'string', description: 'Action (buy/sell)' },
|
||||
type: { type: 'string', description: 'Order type (limit/market)' },
|
||||
status: { type: 'string', description: 'Order status (resting/canceled/executed)' },
|
||||
yes_price: { type: 'number', description: 'Yes price in cents' },
|
||||
no_price: { type: 'number', description: 'No price in cents' },
|
||||
yes_price_dollars: { type: 'string', description: 'Yes price in dollars' },
|
||||
no_price_dollars: { type: 'string', description: 'No price in dollars' },
|
||||
fill_count: { type: 'number', description: 'Filled contract count' },
|
||||
fill_count_fp: { type: 'string', description: 'Filled count (fixed-point)' },
|
||||
remaining_count: { type: 'number', description: 'Remaining contracts' },
|
||||
remaining_count_fp: { type: 'string', description: 'Remaining count (fixed-point)' },
|
||||
initial_count: { type: 'number', description: 'Initial contract count' },
|
||||
initial_count_fp: { type: 'string', description: 'Initial count (fixed-point)' },
|
||||
taker_fees: { type: 'number', description: 'Taker fees in cents' },
|
||||
maker_fees: { type: 'number', description: 'Maker fees in cents' },
|
||||
taker_fees_dollars: { type: 'string', description: 'Taker fees in dollars' },
|
||||
maker_fees_dollars: { type: 'string', description: 'Maker fees in dollars' },
|
||||
taker_fill_cost: { type: 'number', description: 'Taker fill cost in cents' },
|
||||
maker_fill_cost: { type: 'number', description: 'Maker fill cost in cents' },
|
||||
taker_fill_cost_dollars: { type: 'string', description: 'Taker fill cost in dollars' },
|
||||
maker_fill_cost_dollars: { type: 'string', description: 'Maker fill cost in dollars' },
|
||||
queue_position: { type: 'number', description: 'Queue position (deprecated)' },
|
||||
expiration_time: { type: 'string', description: 'Order expiration time' },
|
||||
created_time: { type: 'string', description: 'Order creation time' },
|
||||
last_update_time: { type: 'string', description: 'Last update time' },
|
||||
self_trade_prevention_type: { type: 'string', description: 'Self-trade prevention type' },
|
||||
order_group_id: { type: 'string', description: 'Order group ID' },
|
||||
cancel_order_on_pause: { type: 'boolean', description: 'Cancel on market pause' },
|
||||
},
|
||||
},
|
||||
reduced_by: {
|
||||
type: 'number',
|
||||
description: 'Number of contracts canceled',
|
||||
},
|
||||
reduced_by_fp: {
|
||||
type: 'string',
|
||||
description: 'Number of contracts canceled in fixed-point format',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -209,3 +209,344 @@ export const kalshiCreateOrderTool: ToolConfig<KalshiCreateOrderParams, KalshiCr
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export interface KalshiCreateOrderV2Params extends KalshiAuthParams {
|
||||
ticker: string // Market ticker (required)
|
||||
side: string // 'yes' or 'no' (required)
|
||||
action: string // 'buy' or 'sell' (required)
|
||||
count?: string // Number of contracts (optional - provide count or countFp)
|
||||
type?: string // 'limit' or 'market' (default: limit)
|
||||
yesPrice?: string // Yes price in cents (1-99)
|
||||
noPrice?: string // No price in cents (1-99)
|
||||
yesPriceDollars?: string // Yes price in dollars (e.g., "0.56")
|
||||
noPriceDollars?: string // No price in dollars (e.g., "0.56")
|
||||
clientOrderId?: string // Custom order identifier
|
||||
expirationTs?: string // Unix timestamp expiration
|
||||
timeInForce?: string // 'fill_or_kill', 'good_till_canceled', 'immediate_or_cancel'
|
||||
buyMaxCost?: string // Maximum cost in cents
|
||||
postOnly?: string // 'true' or 'false' - maker-only orders
|
||||
reduceOnly?: string // 'true' or 'false' - position reduction only
|
||||
selfTradePreventionType?: string // 'taker_at_cross' or 'maker'
|
||||
orderGroupId?: string // Associated order group
|
||||
countFp?: string // Count in fixed-point (for fractional contracts)
|
||||
cancelOrderOnPause?: string // 'true' or 'false' - cancel on market pause
|
||||
subaccount?: string // Subaccount to use for the order
|
||||
}
|
||||
|
||||
export interface KalshiCreateOrderV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
order: {
|
||||
order_id: string
|
||||
user_id: string | null
|
||||
client_order_id: string | null
|
||||
ticker: string
|
||||
side: string
|
||||
action: string
|
||||
type: string
|
||||
status: string
|
||||
yes_price: number | null
|
||||
no_price: number | null
|
||||
yes_price_dollars: string | null
|
||||
no_price_dollars: string | null
|
||||
fill_count: number | null
|
||||
fill_count_fp: string | null
|
||||
remaining_count: number | null
|
||||
remaining_count_fp: string | null
|
||||
initial_count: number | null
|
||||
initial_count_fp: string | null
|
||||
taker_fees: number | null
|
||||
maker_fees: number | null
|
||||
taker_fees_dollars: string | null
|
||||
maker_fees_dollars: string | null
|
||||
taker_fill_cost: number | null
|
||||
maker_fill_cost: number | null
|
||||
taker_fill_cost_dollars: string | null
|
||||
maker_fill_cost_dollars: string | null
|
||||
queue_position: number | null
|
||||
expiration_time: string | null
|
||||
created_time: string | null
|
||||
last_update_time: string | null
|
||||
self_trade_prevention_type: string | null
|
||||
order_group_id: string | null
|
||||
cancel_order_on_pause: boolean | null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const kalshiCreateOrderV2Tool: ToolConfig<
|
||||
KalshiCreateOrderV2Params,
|
||||
KalshiCreateOrderV2Response
|
||||
> = {
|
||||
id: 'kalshi_create_order_v2',
|
||||
name: 'Create Order on Kalshi V2',
|
||||
description: 'Create a new order on a Kalshi prediction market (V2 with full API response)',
|
||||
version: '2.0.0',
|
||||
|
||||
params: {
|
||||
keyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your Kalshi API Key ID',
|
||||
},
|
||||
privateKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your RSA Private Key (PEM format)',
|
||||
},
|
||||
ticker: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Market ticker (e.g., KXBTC-24DEC31)',
|
||||
},
|
||||
side: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: "Side of the order: 'yes' or 'no'",
|
||||
},
|
||||
action: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: "Action type: 'buy' or 'sell'",
|
||||
},
|
||||
count: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of contracts (provide count or countFp)',
|
||||
},
|
||||
type: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: "Order type: 'limit' or 'market' (default: limit)",
|
||||
},
|
||||
yesPrice: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Yes price in cents (1-99)',
|
||||
},
|
||||
noPrice: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'No price in cents (1-99)',
|
||||
},
|
||||
yesPriceDollars: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Yes price in dollars (e.g., "0.56")',
|
||||
},
|
||||
noPriceDollars: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'No price in dollars (e.g., "0.56")',
|
||||
},
|
||||
clientOrderId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Custom order identifier',
|
||||
},
|
||||
expirationTs: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Unix timestamp for order expiration',
|
||||
},
|
||||
timeInForce: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: "Time in force: 'fill_or_kill', 'good_till_canceled', 'immediate_or_cancel'",
|
||||
},
|
||||
buyMaxCost: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum cost in cents (auto-enables fill_or_kill)',
|
||||
},
|
||||
postOnly: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: "Set to 'true' for maker-only orders",
|
||||
},
|
||||
reduceOnly: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: "Set to 'true' for position reduction only",
|
||||
},
|
||||
selfTradePreventionType: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: "Self-trade prevention: 'taker_at_cross' or 'maker'",
|
||||
},
|
||||
orderGroupId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Associated order group ID',
|
||||
},
|
||||
countFp: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Count in fixed-point for fractional contracts',
|
||||
},
|
||||
cancelOrderOnPause: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: "Set to 'true' to cancel order on market pause",
|
||||
},
|
||||
subaccount: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Subaccount to use for the order',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: () => buildKalshiUrl('/portfolio/orders'),
|
||||
method: 'POST',
|
||||
headers: (params) => {
|
||||
const path = '/trade-api/v2/portfolio/orders'
|
||||
return buildKalshiAuthHeaders(params.keyId, params.privateKey, 'POST', path)
|
||||
},
|
||||
body: (params) => {
|
||||
const body: Record<string, any> = {
|
||||
ticker: params.ticker,
|
||||
side: params.side.toLowerCase(),
|
||||
action: params.action.toLowerCase(),
|
||||
}
|
||||
|
||||
// count or count_fp must be provided (but not both required)
|
||||
if (params.count) body.count = Number.parseInt(params.count, 10)
|
||||
if (params.countFp) body.count_fp = params.countFp
|
||||
if (params.type) body.type = params.type.toLowerCase()
|
||||
if (params.yesPrice) body.yes_price = Number.parseInt(params.yesPrice, 10)
|
||||
if (params.noPrice) body.no_price = Number.parseInt(params.noPrice, 10)
|
||||
if (params.yesPriceDollars) body.yes_price_dollars = params.yesPriceDollars
|
||||
if (params.noPriceDollars) body.no_price_dollars = params.noPriceDollars
|
||||
if (params.clientOrderId) body.client_order_id = params.clientOrderId
|
||||
if (params.expirationTs) body.expiration_ts = Number.parseInt(params.expirationTs, 10)
|
||||
if (params.timeInForce) body.time_in_force = params.timeInForce
|
||||
if (params.buyMaxCost) body.buy_max_cost = Number.parseInt(params.buyMaxCost, 10)
|
||||
if (params.postOnly) body.post_only = params.postOnly === 'true'
|
||||
if (params.reduceOnly) body.reduce_only = params.reduceOnly === 'true'
|
||||
if (params.selfTradePreventionType)
|
||||
body.self_trade_prevention_type = params.selfTradePreventionType
|
||||
if (params.orderGroupId) body.order_group_id = params.orderGroupId
|
||||
if (params.cancelOrderOnPause)
|
||||
body.cancel_order_on_pause = params.cancelOrderOnPause === 'true'
|
||||
if (params.subaccount) body.subaccount = params.subaccount
|
||||
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handleKalshiError(data, response.status, 'create_order_v2')
|
||||
}
|
||||
|
||||
const order = data.order || {}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
order: {
|
||||
order_id: order.order_id ?? null,
|
||||
user_id: order.user_id ?? null,
|
||||
client_order_id: order.client_order_id ?? null,
|
||||
ticker: order.ticker ?? null,
|
||||
side: order.side ?? null,
|
||||
action: order.action ?? null,
|
||||
type: order.type ?? null,
|
||||
status: order.status ?? null,
|
||||
yes_price: order.yes_price ?? null,
|
||||
no_price: order.no_price ?? null,
|
||||
yes_price_dollars: order.yes_price_dollars ?? null,
|
||||
no_price_dollars: order.no_price_dollars ?? null,
|
||||
fill_count: order.fill_count ?? null,
|
||||
fill_count_fp: order.fill_count_fp ?? null,
|
||||
remaining_count: order.remaining_count ?? null,
|
||||
remaining_count_fp: order.remaining_count_fp ?? null,
|
||||
initial_count: order.initial_count ?? null,
|
||||
initial_count_fp: order.initial_count_fp ?? null,
|
||||
taker_fees: order.taker_fees ?? null,
|
||||
maker_fees: order.maker_fees ?? null,
|
||||
taker_fees_dollars: order.taker_fees_dollars ?? null,
|
||||
maker_fees_dollars: order.maker_fees_dollars ?? null,
|
||||
taker_fill_cost: order.taker_fill_cost ?? null,
|
||||
maker_fill_cost: order.maker_fill_cost ?? null,
|
||||
taker_fill_cost_dollars: order.taker_fill_cost_dollars ?? null,
|
||||
maker_fill_cost_dollars: order.maker_fill_cost_dollars ?? null,
|
||||
queue_position: order.queue_position ?? null,
|
||||
expiration_time: order.expiration_time ?? null,
|
||||
created_time: order.created_time ?? null,
|
||||
last_update_time: order.last_update_time ?? null,
|
||||
self_trade_prevention_type: order.self_trade_prevention_type ?? null,
|
||||
order_group_id: order.order_group_id ?? null,
|
||||
cancel_order_on_pause: order.cancel_order_on_pause ?? null,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
order: {
|
||||
type: 'object',
|
||||
description: 'The created order object with full API response fields',
|
||||
properties: {
|
||||
order_id: { type: 'string', description: 'Order ID' },
|
||||
user_id: { type: 'string', description: 'User ID' },
|
||||
client_order_id: { type: 'string', description: 'Client order ID' },
|
||||
ticker: { type: 'string', description: 'Market ticker' },
|
||||
side: { type: 'string', description: 'Order side (yes/no)' },
|
||||
action: { type: 'string', description: 'Action (buy/sell)' },
|
||||
type: { type: 'string', description: 'Order type (limit/market)' },
|
||||
status: { type: 'string', description: 'Order status (resting/canceled/executed)' },
|
||||
yes_price: { type: 'number', description: 'Yes price in cents' },
|
||||
no_price: { type: 'number', description: 'No price in cents' },
|
||||
yes_price_dollars: { type: 'string', description: 'Yes price in dollars' },
|
||||
no_price_dollars: { type: 'string', description: 'No price in dollars' },
|
||||
fill_count: { type: 'number', description: 'Filled contract count' },
|
||||
fill_count_fp: { type: 'string', description: 'Filled count (fixed-point)' },
|
||||
remaining_count: { type: 'number', description: 'Remaining contracts' },
|
||||
remaining_count_fp: { type: 'string', description: 'Remaining count (fixed-point)' },
|
||||
initial_count: { type: 'number', description: 'Initial contract count' },
|
||||
initial_count_fp: { type: 'string', description: 'Initial count (fixed-point)' },
|
||||
taker_fees: { type: 'number', description: 'Taker fees in cents' },
|
||||
maker_fees: { type: 'number', description: 'Maker fees in cents' },
|
||||
taker_fees_dollars: { type: 'string', description: 'Taker fees in dollars' },
|
||||
maker_fees_dollars: { type: 'string', description: 'Maker fees in dollars' },
|
||||
taker_fill_cost: { type: 'number', description: 'Taker fill cost in cents' },
|
||||
maker_fill_cost: { type: 'number', description: 'Maker fill cost in cents' },
|
||||
taker_fill_cost_dollars: { type: 'string', description: 'Taker fill cost in dollars' },
|
||||
maker_fill_cost_dollars: { type: 'string', description: 'Maker fill cost in dollars' },
|
||||
queue_position: { type: 'number', description: 'Queue position (deprecated)' },
|
||||
expiration_time: { type: 'string', description: 'Order expiration time' },
|
||||
created_time: { type: 'string', description: 'Order creation time' },
|
||||
last_update_time: { type: 'string', description: 'Last update time' },
|
||||
self_trade_prevention_type: { type: 'string', description: 'Self-trade prevention type' },
|
||||
order_group_id: { type: 'string', description: 'Order group ID' },
|
||||
cancel_order_on_pause: { type: 'boolean', description: 'Cancel on market pause' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -66,3 +66,78 @@ export const kalshiGetBalanceTool: ToolConfig<KalshiGetBalanceParams, KalshiGetB
|
||||
portfolioValue: { type: 'number', description: 'Portfolio value in cents' },
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 Params for Get Balance
|
||||
*/
|
||||
export interface KalshiGetBalanceV2Params extends KalshiAuthParams {}
|
||||
|
||||
/**
|
||||
* V2 Response matching Kalshi API exactly
|
||||
*/
|
||||
export interface KalshiGetBalanceV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
balance: number
|
||||
portfolio_value: number
|
||||
updated_ts: number | null
|
||||
}
|
||||
}
|
||||
|
||||
export const kalshiGetBalanceV2Tool: ToolConfig<
|
||||
KalshiGetBalanceV2Params,
|
||||
KalshiGetBalanceV2Response
|
||||
> = {
|
||||
id: 'kalshi_get_balance_v2',
|
||||
name: 'Get Balance from Kalshi V2',
|
||||
description:
|
||||
'Retrieve your account balance and portfolio value from Kalshi (V2 - exact API response)',
|
||||
version: '2.0.0',
|
||||
|
||||
params: {
|
||||
keyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your Kalshi API Key ID',
|
||||
},
|
||||
privateKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your RSA Private Key (PEM format)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: () => buildKalshiUrl('/portfolio/balance'),
|
||||
method: 'GET',
|
||||
headers: (params) => {
|
||||
const path = '/trade-api/v2/portfolio/balance'
|
||||
return buildKalshiAuthHeaders(params.keyId, params.privateKey, 'GET', path)
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handleKalshiError(data, response.status, 'get_balance_v2')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
balance: data.balance ?? 0,
|
||||
portfolio_value: data.portfolio_value ?? 0,
|
||||
updated_ts: data.updated_ts ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
balance: { type: 'number', description: 'Account balance in cents' },
|
||||
portfolio_value: { type: 'number', description: 'Portfolio value in cents' },
|
||||
updated_ts: { type: 'number', description: 'Unix timestamp of last update (milliseconds)' },
|
||||
},
|
||||
}
|
||||
|
||||
@@ -102,3 +102,246 @@ export const kalshiGetCandlesticksTool: ToolConfig<
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* BidAskDistribution - OHLC data for yes_bid and yes_ask
|
||||
*/
|
||||
export interface BidAskDistribution {
|
||||
open: number | null
|
||||
open_dollars: string | null
|
||||
low: number | null
|
||||
low_dollars: string | null
|
||||
high: number | null
|
||||
high_dollars: string | null
|
||||
close: number | null
|
||||
close_dollars: string | null
|
||||
}
|
||||
|
||||
/**
|
||||
* PriceDistribution - Extended OHLC data for price field
|
||||
*/
|
||||
export interface PriceDistribution {
|
||||
open: number | null
|
||||
open_dollars: string | null
|
||||
low: number | null
|
||||
low_dollars: string | null
|
||||
high: number | null
|
||||
high_dollars: string | null
|
||||
close: number | null
|
||||
close_dollars: string | null
|
||||
mean: number | null
|
||||
mean_dollars: string | null
|
||||
previous: number | null
|
||||
previous_dollars: string | null
|
||||
min: number | null
|
||||
min_dollars: string | null
|
||||
max: number | null
|
||||
max_dollars: string | null
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 Get Candlesticks Tool - Returns exact Kalshi API response structure
|
||||
*/
|
||||
export interface KalshiGetCandlesticksV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
ticker: string
|
||||
candlesticks: Array<{
|
||||
end_period_ts: number | null
|
||||
yes_bid: BidAskDistribution
|
||||
yes_ask: BidAskDistribution
|
||||
price: PriceDistribution
|
||||
volume: number | null
|
||||
volume_fp: string | null
|
||||
open_interest: number | null
|
||||
open_interest_fp: string | null
|
||||
}>
|
||||
}
|
||||
}
|
||||
|
||||
export const kalshiGetCandlesticksV2Tool: ToolConfig<
|
||||
KalshiGetCandlesticksParams,
|
||||
KalshiGetCandlesticksV2Response
|
||||
> = {
|
||||
id: 'kalshi_get_candlesticks_v2',
|
||||
name: 'Get Market Candlesticks from Kalshi V2',
|
||||
description: 'Retrieve OHLC candlestick data for a specific market (V2 - full API response)',
|
||||
version: '2.0.0',
|
||||
|
||||
params: {
|
||||
seriesTicker: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Series ticker',
|
||||
},
|
||||
ticker: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Market ticker (e.g., KXBTC-24DEC31)',
|
||||
},
|
||||
startTs: {
|
||||
type: 'number',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Start timestamp (Unix seconds)',
|
||||
},
|
||||
endTs: {
|
||||
type: 'number',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'End timestamp (Unix seconds)',
|
||||
},
|
||||
periodInterval: {
|
||||
type: 'number',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Period interval: 1 (1min), 60 (1hour), or 1440 (1day)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
queryParams.append('start_ts', params.startTs.toString())
|
||||
queryParams.append('end_ts', params.endTs.toString())
|
||||
queryParams.append('period_interval', params.periodInterval.toString())
|
||||
|
||||
const query = queryParams.toString()
|
||||
const url = buildKalshiUrl(
|
||||
`/series/${params.seriesTicker}/markets/${params.ticker}/candlesticks`
|
||||
)
|
||||
return `${url}?${query}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handleKalshiError(data, response.status, 'get_candlesticks_v2')
|
||||
}
|
||||
|
||||
const mapBidAsk = (obj: Record<string, unknown> | null): BidAskDistribution => ({
|
||||
open: (obj?.open as number) ?? null,
|
||||
open_dollars: (obj?.open_dollars as string) ?? null,
|
||||
low: (obj?.low as number) ?? null,
|
||||
low_dollars: (obj?.low_dollars as string) ?? null,
|
||||
high: (obj?.high as number) ?? null,
|
||||
high_dollars: (obj?.high_dollars as string) ?? null,
|
||||
close: (obj?.close as number) ?? null,
|
||||
close_dollars: (obj?.close_dollars as string) ?? null,
|
||||
})
|
||||
|
||||
const mapPrice = (obj: Record<string, unknown> | null): PriceDistribution => ({
|
||||
open: (obj?.open as number) ?? null,
|
||||
open_dollars: (obj?.open_dollars as string) ?? null,
|
||||
low: (obj?.low as number) ?? null,
|
||||
low_dollars: (obj?.low_dollars as string) ?? null,
|
||||
high: (obj?.high as number) ?? null,
|
||||
high_dollars: (obj?.high_dollars as string) ?? null,
|
||||
close: (obj?.close as number) ?? null,
|
||||
close_dollars: (obj?.close_dollars as string) ?? null,
|
||||
mean: (obj?.mean as number) ?? null,
|
||||
mean_dollars: (obj?.mean_dollars as string) ?? null,
|
||||
previous: (obj?.previous as number) ?? null,
|
||||
previous_dollars: (obj?.previous_dollars as string) ?? null,
|
||||
min: (obj?.min as number) ?? null,
|
||||
min_dollars: (obj?.min_dollars as string) ?? null,
|
||||
max: (obj?.max as number) ?? null,
|
||||
max_dollars: (obj?.max_dollars as string) ?? null,
|
||||
})
|
||||
|
||||
const candlesticks = (data.candlesticks || []).map((c: Record<string, unknown>) => ({
|
||||
end_period_ts: (c.end_period_ts as number) ?? null,
|
||||
yes_bid: mapBidAsk(c.yes_bid as Record<string, unknown> | null),
|
||||
yes_ask: mapBidAsk(c.yes_ask as Record<string, unknown> | null),
|
||||
price: mapPrice(c.price as Record<string, unknown> | null),
|
||||
volume: (c.volume as number) ?? null,
|
||||
volume_fp: (c.volume_fp as string) ?? null,
|
||||
open_interest: (c.open_interest as number) ?? null,
|
||||
open_interest_fp: (c.open_interest_fp as string) ?? null,
|
||||
}))
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
ticker: data.ticker ?? null,
|
||||
candlesticks,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
ticker: {
|
||||
type: 'string',
|
||||
description: 'Market ticker',
|
||||
},
|
||||
candlesticks: {
|
||||
type: 'array',
|
||||
description: 'Array of OHLC candlestick data with nested bid/ask/price objects',
|
||||
properties: {
|
||||
end_period_ts: { type: 'number', description: 'End period timestamp (Unix)' },
|
||||
yes_bid: {
|
||||
type: 'object',
|
||||
description: 'Yes bid OHLC data',
|
||||
properties: {
|
||||
open: { type: 'number', description: 'Open price (cents)' },
|
||||
open_dollars: { type: 'string', description: 'Open price (dollars)' },
|
||||
low: { type: 'number', description: 'Low price (cents)' },
|
||||
low_dollars: { type: 'string', description: 'Low price (dollars)' },
|
||||
high: { type: 'number', description: 'High price (cents)' },
|
||||
high_dollars: { type: 'string', description: 'High price (dollars)' },
|
||||
close: { type: 'number', description: 'Close price (cents)' },
|
||||
close_dollars: { type: 'string', description: 'Close price (dollars)' },
|
||||
},
|
||||
},
|
||||
yes_ask: {
|
||||
type: 'object',
|
||||
description: 'Yes ask OHLC data',
|
||||
properties: {
|
||||
open: { type: 'number', description: 'Open price (cents)' },
|
||||
open_dollars: { type: 'string', description: 'Open price (dollars)' },
|
||||
low: { type: 'number', description: 'Low price (cents)' },
|
||||
low_dollars: { type: 'string', description: 'Low price (dollars)' },
|
||||
high: { type: 'number', description: 'High price (cents)' },
|
||||
high_dollars: { type: 'string', description: 'High price (dollars)' },
|
||||
close: { type: 'number', description: 'Close price (cents)' },
|
||||
close_dollars: { type: 'string', description: 'Close price (dollars)' },
|
||||
},
|
||||
},
|
||||
price: {
|
||||
type: 'object',
|
||||
description: 'Trade price OHLC data with additional statistics',
|
||||
properties: {
|
||||
open: { type: 'number', description: 'Open price (cents)' },
|
||||
open_dollars: { type: 'string', description: 'Open price (dollars)' },
|
||||
low: { type: 'number', description: 'Low price (cents)' },
|
||||
low_dollars: { type: 'string', description: 'Low price (dollars)' },
|
||||
high: { type: 'number', description: 'High price (cents)' },
|
||||
high_dollars: { type: 'string', description: 'High price (dollars)' },
|
||||
close: { type: 'number', description: 'Close price (cents)' },
|
||||
close_dollars: { type: 'string', description: 'Close price (dollars)' },
|
||||
mean: { type: 'number', description: 'Mean price (cents)' },
|
||||
mean_dollars: { type: 'string', description: 'Mean price (dollars)' },
|
||||
previous: { type: 'number', description: 'Previous price (cents)' },
|
||||
previous_dollars: { type: 'string', description: 'Previous price (dollars)' },
|
||||
min: { type: 'number', description: 'Min price (cents)' },
|
||||
min_dollars: { type: 'string', description: 'Min price (dollars)' },
|
||||
max: { type: 'number', description: 'Max price (cents)' },
|
||||
max_dollars: { type: 'string', description: 'Max price (dollars)' },
|
||||
},
|
||||
},
|
||||
volume: { type: 'number', description: 'Volume (contracts)' },
|
||||
volume_fp: { type: 'string', description: 'Volume (fixed-point string)' },
|
||||
open_interest: { type: 'number', description: 'Open interest (contracts)' },
|
||||
open_interest_fp: { type: 'string', description: 'Open interest (fixed-point string)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -73,3 +73,179 @@ export const kalshiGetEventTool: ToolConfig<KalshiGetEventParams, KalshiGetEvent
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 Params for Get Event
|
||||
*/
|
||||
export interface KalshiGetEventV2Params {
|
||||
eventTicker: string
|
||||
withNestedMarkets?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 Response matching Kalshi API exactly
|
||||
*/
|
||||
export interface KalshiGetEventV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
event: {
|
||||
event_ticker: string
|
||||
series_ticker: string
|
||||
title: string
|
||||
sub_title: string | null
|
||||
mutually_exclusive: boolean
|
||||
category: string
|
||||
collateral_return_type: string | null
|
||||
strike_date: string | null
|
||||
strike_period: string | null
|
||||
available_on_brokers: boolean | null
|
||||
product_metadata: Record<string, unknown> | null
|
||||
markets: Array<{
|
||||
ticker: string
|
||||
event_ticker: string
|
||||
market_type: string
|
||||
title: string
|
||||
subtitle: string | null
|
||||
yes_sub_title: string | null
|
||||
no_sub_title: string | null
|
||||
open_time: string
|
||||
close_time: string
|
||||
expiration_time: string
|
||||
status: string
|
||||
yes_bid: number
|
||||
yes_ask: number
|
||||
no_bid: number
|
||||
no_ask: number
|
||||
last_price: number
|
||||
previous_yes_bid: number | null
|
||||
previous_yes_ask: number | null
|
||||
previous_price: number | null
|
||||
volume: number
|
||||
volume_24h: number
|
||||
liquidity: number | null
|
||||
open_interest: number | null
|
||||
result: string | null
|
||||
cap_strike: number | null
|
||||
floor_strike: number | null
|
||||
}> | null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const kalshiGetEventV2Tool: ToolConfig<KalshiGetEventV2Params, KalshiGetEventV2Response> = {
|
||||
id: 'kalshi_get_event_v2',
|
||||
name: 'Get Event from Kalshi V2',
|
||||
description: 'Retrieve details of a specific event by ticker (V2 - exact API response)',
|
||||
version: '2.0.0',
|
||||
|
||||
params: {
|
||||
eventTicker: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The event ticker',
|
||||
},
|
||||
withNestedMarkets: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Include nested markets in response (true/false)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.withNestedMarkets)
|
||||
queryParams.append('with_nested_markets', params.withNestedMarkets)
|
||||
|
||||
const query = queryParams.toString()
|
||||
const url = buildKalshiUrl(`/events/${params.eventTicker}`)
|
||||
return query ? `${url}?${query}` : url
|
||||
},
|
||||
method: 'GET',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handleKalshiError(data, response.status, 'get_event_v2')
|
||||
}
|
||||
|
||||
const event = data.event || {}
|
||||
const markets =
|
||||
event.markets?.map((m: Record<string, unknown>) => ({
|
||||
ticker: m.ticker ?? null,
|
||||
event_ticker: m.event_ticker ?? null,
|
||||
market_type: m.market_type ?? null,
|
||||
title: m.title ?? null,
|
||||
subtitle: m.subtitle ?? null,
|
||||
yes_sub_title: m.yes_sub_title ?? null,
|
||||
no_sub_title: m.no_sub_title ?? null,
|
||||
open_time: m.open_time ?? null,
|
||||
close_time: m.close_time ?? null,
|
||||
expiration_time: m.expiration_time ?? null,
|
||||
status: m.status ?? null,
|
||||
yes_bid: m.yes_bid ?? 0,
|
||||
yes_ask: m.yes_ask ?? 0,
|
||||
no_bid: m.no_bid ?? 0,
|
||||
no_ask: m.no_ask ?? 0,
|
||||
last_price: m.last_price ?? 0,
|
||||
previous_yes_bid: m.previous_yes_bid ?? null,
|
||||
previous_yes_ask: m.previous_yes_ask ?? null,
|
||||
previous_price: m.previous_price ?? null,
|
||||
volume: m.volume ?? 0,
|
||||
volume_24h: m.volume_24h ?? 0,
|
||||
liquidity: m.liquidity ?? null,
|
||||
open_interest: m.open_interest ?? null,
|
||||
result: m.result ?? null,
|
||||
cap_strike: m.cap_strike ?? null,
|
||||
floor_strike: m.floor_strike ?? null,
|
||||
})) ?? null
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
event: {
|
||||
event_ticker: event.event_ticker ?? null,
|
||||
series_ticker: event.series_ticker ?? null,
|
||||
title: event.title ?? null,
|
||||
sub_title: event.sub_title ?? null,
|
||||
mutually_exclusive: event.mutually_exclusive ?? false,
|
||||
category: event.category ?? null,
|
||||
collateral_return_type: event.collateral_return_type ?? null,
|
||||
strike_date: event.strike_date ?? null,
|
||||
strike_period: event.strike_period ?? null,
|
||||
available_on_brokers: event.available_on_brokers ?? null,
|
||||
product_metadata: event.product_metadata ?? null,
|
||||
markets,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
event: {
|
||||
type: 'object',
|
||||
description: 'Event object with full details matching Kalshi API response',
|
||||
properties: {
|
||||
event_ticker: { type: 'string', description: 'Event ticker' },
|
||||
series_ticker: { type: 'string', description: 'Series ticker' },
|
||||
title: { type: 'string', description: 'Event title' },
|
||||
sub_title: { type: 'string', description: 'Event subtitle' },
|
||||
mutually_exclusive: { type: 'boolean', description: 'Mutually exclusive markets' },
|
||||
category: { type: 'string', description: 'Event category' },
|
||||
collateral_return_type: { type: 'string', description: 'Collateral return type' },
|
||||
strike_date: { type: 'string', description: 'Strike date' },
|
||||
strike_period: { type: 'string', description: 'Strike period' },
|
||||
available_on_brokers: { type: 'boolean', description: 'Available on brokers' },
|
||||
product_metadata: { type: 'object', description: 'Product metadata' },
|
||||
markets: { type: 'array', description: 'Nested markets (if requested)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -106,3 +106,197 @@ export const kalshiGetEventsTool: ToolConfig<KalshiGetEventsParams, KalshiGetEve
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 Params for Get Events
|
||||
*/
|
||||
export interface KalshiGetEventsV2Params extends KalshiPaginationParams {
|
||||
status?: string
|
||||
seriesTicker?: string
|
||||
withNestedMarkets?: string
|
||||
withMilestones?: string
|
||||
minCloseTs?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 Response matching Kalshi API exactly
|
||||
*/
|
||||
export interface KalshiGetEventsV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
events: Array<{
|
||||
event_ticker: string
|
||||
series_ticker: string
|
||||
title: string
|
||||
sub_title: string | null
|
||||
mutually_exclusive: boolean
|
||||
category: string
|
||||
collateral_return_type: string | null
|
||||
strike_date: string | null
|
||||
strike_period: string | null
|
||||
available_on_brokers: boolean | null
|
||||
product_metadata: Record<string, unknown> | null
|
||||
markets: Array<Record<string, unknown>> | null
|
||||
}>
|
||||
milestones: Array<{
|
||||
event_ticker: string
|
||||
milestone_type: string
|
||||
milestone_date: string
|
||||
milestone_title: string | null
|
||||
}> | null
|
||||
cursor: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export const kalshiGetEventsV2Tool: ToolConfig<KalshiGetEventsV2Params, KalshiGetEventsV2Response> =
|
||||
{
|
||||
id: 'kalshi_get_events_v2',
|
||||
name: 'Get Events from Kalshi V2',
|
||||
description:
|
||||
'Retrieve a list of events from Kalshi with optional filtering (V2 - exact API response)',
|
||||
version: '2.0.0',
|
||||
|
||||
params: {
|
||||
status: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by status (open, closed, settled)',
|
||||
},
|
||||
seriesTicker: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by series ticker',
|
||||
},
|
||||
withNestedMarkets: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Include nested markets in response (true/false)',
|
||||
},
|
||||
withMilestones: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Include milestones in response (true/false)',
|
||||
},
|
||||
minCloseTs: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Minimum close timestamp (Unix seconds)',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of results (1-200, default: 200)',
|
||||
},
|
||||
cursor: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination cursor for next page',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.status) queryParams.append('status', params.status)
|
||||
if (params.seriesTicker) queryParams.append('series_ticker', params.seriesTicker)
|
||||
if (params.withNestedMarkets)
|
||||
queryParams.append('with_nested_markets', params.withNestedMarkets)
|
||||
if (params.withMilestones) queryParams.append('with_milestones', params.withMilestones)
|
||||
if (params.minCloseTs !== undefined)
|
||||
queryParams.append('min_close_ts', params.minCloseTs.toString())
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.cursor) queryParams.append('cursor', params.cursor)
|
||||
|
||||
const query = queryParams.toString()
|
||||
const url = buildKalshiUrl('/events')
|
||||
return query ? `${url}?${query}` : url
|
||||
},
|
||||
method: 'GET',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handleKalshiError(data, response.status, 'get_events_v2')
|
||||
}
|
||||
|
||||
const events = (data.events || []).map((e: Record<string, unknown>) => ({
|
||||
event_ticker: e.event_ticker ?? null,
|
||||
series_ticker: e.series_ticker ?? null,
|
||||
title: e.title ?? null,
|
||||
sub_title: e.sub_title ?? null,
|
||||
mutually_exclusive: e.mutually_exclusive ?? false,
|
||||
category: e.category ?? null,
|
||||
collateral_return_type: e.collateral_return_type ?? null,
|
||||
strike_date: e.strike_date ?? null,
|
||||
strike_period: e.strike_period ?? null,
|
||||
available_on_brokers: e.available_on_brokers ?? null,
|
||||
product_metadata: e.product_metadata ?? null,
|
||||
markets: e.markets ?? null,
|
||||
}))
|
||||
|
||||
const milestones = data.milestones
|
||||
? (data.milestones as Array<Record<string, unknown>>).map((m) => ({
|
||||
event_ticker: (m.event_ticker as string) ?? '',
|
||||
milestone_type: (m.milestone_type as string) ?? '',
|
||||
milestone_date: (m.milestone_date as string) ?? '',
|
||||
milestone_title: (m.milestone_title as string | null) ?? null,
|
||||
}))
|
||||
: null
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
events,
|
||||
milestones,
|
||||
cursor: data.cursor ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
events: {
|
||||
type: 'array',
|
||||
description: 'Array of event objects',
|
||||
properties: {
|
||||
event_ticker: { type: 'string', description: 'Event ticker' },
|
||||
series_ticker: { type: 'string', description: 'Series ticker' },
|
||||
title: { type: 'string', description: 'Event title' },
|
||||
sub_title: { type: 'string', description: 'Event subtitle' },
|
||||
mutually_exclusive: { type: 'boolean', description: 'Mutually exclusive markets' },
|
||||
category: { type: 'string', description: 'Event category' },
|
||||
collateral_return_type: { type: 'string', description: 'Collateral return type' },
|
||||
strike_date: { type: 'string', description: 'Strike date' },
|
||||
strike_period: { type: 'string', description: 'Strike period' },
|
||||
available_on_brokers: { type: 'boolean', description: 'Available on brokers' },
|
||||
product_metadata: { type: 'object', description: 'Product metadata' },
|
||||
markets: { type: 'array', description: 'Nested markets (if requested)' },
|
||||
},
|
||||
},
|
||||
milestones: {
|
||||
type: 'array',
|
||||
description: 'Array of milestone objects (if requested)',
|
||||
properties: {
|
||||
event_ticker: { type: 'string', description: 'Event ticker' },
|
||||
milestone_type: { type: 'string', description: 'Milestone type' },
|
||||
milestone_date: { type: 'string', description: 'Milestone date' },
|
||||
milestone_title: { type: 'string', description: 'Milestone title' },
|
||||
},
|
||||
},
|
||||
cursor: {
|
||||
type: 'string',
|
||||
description: 'Pagination cursor for fetching more results',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -59,3 +59,74 @@ export const kalshiGetExchangeStatusTool: ToolConfig<
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 Params for Get Exchange Status
|
||||
*/
|
||||
export type KalshiGetExchangeStatusV2Params = Record<string, never>
|
||||
|
||||
/**
|
||||
* V2 Response matching Kalshi API exactly
|
||||
*/
|
||||
export interface KalshiGetExchangeStatusV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
exchange_active: boolean
|
||||
trading_active: boolean
|
||||
exchange_estimated_resume_time: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export const kalshiGetExchangeStatusV2Tool: ToolConfig<
|
||||
KalshiGetExchangeStatusV2Params,
|
||||
KalshiGetExchangeStatusV2Response
|
||||
> = {
|
||||
id: 'kalshi_get_exchange_status_v2',
|
||||
name: 'Get Exchange Status from Kalshi V2',
|
||||
description: 'Retrieve the current status of the Kalshi exchange (V2 - exact API response)',
|
||||
version: '2.0.0',
|
||||
|
||||
params: {},
|
||||
|
||||
request: {
|
||||
url: () => {
|
||||
return buildKalshiUrl('/exchange/status')
|
||||
},
|
||||
method: 'GET',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handleKalshiError(data, response.status, 'get_exchange_status_v2')
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
exchange_active: data.exchange_active ?? false,
|
||||
trading_active: data.trading_active ?? false,
|
||||
exchange_estimated_resume_time: data.exchange_estimated_resume_time ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
exchange_active: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the exchange is active',
|
||||
},
|
||||
trading_active: {
|
||||
type: 'boolean',
|
||||
description: 'Whether trading is active',
|
||||
},
|
||||
exchange_estimated_resume_time: {
|
||||
type: 'string',
|
||||
description: 'Estimated time when exchange will resume (if inactive)',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -131,3 +131,198 @@ export const kalshiGetFillsTool: ToolConfig<KalshiGetFillsParams, KalshiGetFills
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 Params for Get Fills - fixes limit max to 200, adds subaccount
|
||||
*/
|
||||
export interface KalshiGetFillsV2Params extends KalshiAuthParams, KalshiPaginationParams {
|
||||
ticker?: string
|
||||
orderId?: string
|
||||
minTs?: number
|
||||
maxTs?: number
|
||||
subaccount?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 Response matching Kalshi API exactly
|
||||
*/
|
||||
export interface KalshiGetFillsV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
fills: Array<{
|
||||
fill_id: string
|
||||
trade_id: string
|
||||
order_id: string
|
||||
client_order_id: string | null
|
||||
ticker: string
|
||||
market_ticker: string
|
||||
side: string
|
||||
action: string
|
||||
count: number
|
||||
count_fp: string | null
|
||||
price: number | null
|
||||
yes_price: number
|
||||
no_price: number
|
||||
yes_price_fixed: string | null
|
||||
no_price_fixed: string | null
|
||||
is_taker: boolean
|
||||
created_time: string | null
|
||||
ts: number | null
|
||||
}>
|
||||
cursor: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export const kalshiGetFillsV2Tool: ToolConfig<KalshiGetFillsV2Params, KalshiGetFillsV2Response> = {
|
||||
id: 'kalshi_get_fills_v2',
|
||||
name: 'Get Fills from Kalshi V2',
|
||||
description: "Retrieve your portfolio's fills/trades from Kalshi (V2 - exact API response)",
|
||||
version: '2.0.0',
|
||||
|
||||
params: {
|
||||
keyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your Kalshi API Key ID',
|
||||
},
|
||||
privateKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your RSA Private Key (PEM format)',
|
||||
},
|
||||
ticker: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by market ticker',
|
||||
},
|
||||
orderId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by order ID',
|
||||
},
|
||||
minTs: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Minimum timestamp (Unix milliseconds)',
|
||||
},
|
||||
maxTs: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum timestamp (Unix milliseconds)',
|
||||
},
|
||||
subaccount: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Subaccount to get fills for',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of results (1-200, default: 100)',
|
||||
},
|
||||
cursor: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination cursor for next page',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.ticker) queryParams.append('ticker', params.ticker)
|
||||
if (params.orderId) queryParams.append('order_id', params.orderId)
|
||||
if (params.minTs !== undefined) queryParams.append('min_ts', params.minTs.toString())
|
||||
if (params.maxTs !== undefined) queryParams.append('max_ts', params.maxTs.toString())
|
||||
if (params.subaccount) queryParams.append('subaccount', params.subaccount)
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.cursor) queryParams.append('cursor', params.cursor)
|
||||
|
||||
const query = queryParams.toString()
|
||||
const url = buildKalshiUrl('/portfolio/fills')
|
||||
return query ? `${url}?${query}` : url
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => {
|
||||
const path = '/trade-api/v2/portfolio/fills'
|
||||
return buildKalshiAuthHeaders(params.keyId, params.privateKey, 'GET', path)
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handleKalshiError(data, response.status, 'get_fills_v2')
|
||||
}
|
||||
|
||||
const fills = (data.fills || []).map((f: Record<string, unknown>) => ({
|
||||
fill_id: f.fill_id ?? null,
|
||||
trade_id: f.trade_id ?? null,
|
||||
order_id: f.order_id ?? null,
|
||||
client_order_id: f.client_order_id ?? null,
|
||||
ticker: f.ticker ?? null,
|
||||
market_ticker: f.market_ticker ?? null,
|
||||
side: f.side ?? null,
|
||||
action: f.action ?? null,
|
||||
count: f.count ?? 0,
|
||||
count_fp: f.count_fp ?? null,
|
||||
price: f.price ?? null,
|
||||
yes_price: f.yes_price ?? 0,
|
||||
no_price: f.no_price ?? 0,
|
||||
yes_price_fixed: f.yes_price_fixed ?? null,
|
||||
no_price_fixed: f.no_price_fixed ?? null,
|
||||
is_taker: f.is_taker ?? false,
|
||||
created_time: f.created_time ?? null,
|
||||
ts: f.ts ?? null,
|
||||
}))
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
fills,
|
||||
cursor: data.cursor ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
fills: {
|
||||
type: 'array',
|
||||
description: 'Array of fill/trade objects with all API fields',
|
||||
properties: {
|
||||
fill_id: { type: 'string', description: 'Fill ID' },
|
||||
trade_id: { type: 'string', description: 'Trade ID (same as fill_id)' },
|
||||
order_id: { type: 'string', description: 'Order ID' },
|
||||
client_order_id: { type: 'string', description: 'Client order ID' },
|
||||
ticker: { type: 'string', description: 'Market ticker' },
|
||||
market_ticker: { type: 'string', description: 'Market ticker (legacy)' },
|
||||
side: { type: 'string', description: 'Side (yes/no)' },
|
||||
action: { type: 'string', description: 'Action (buy/sell)' },
|
||||
count: { type: 'number', description: 'Number of contracts' },
|
||||
count_fp: { type: 'string', description: 'Count (fixed-point)' },
|
||||
price: { type: 'number', description: 'Price (deprecated)' },
|
||||
yes_price: { type: 'number', description: 'Yes price in cents' },
|
||||
no_price: { type: 'number', description: 'No price in cents' },
|
||||
yes_price_fixed: { type: 'string', description: 'Yes price in dollars' },
|
||||
no_price_fixed: { type: 'string', description: 'No price in dollars' },
|
||||
is_taker: { type: 'boolean', description: 'Whether fill was taker' },
|
||||
created_time: { type: 'string', description: 'Fill creation time' },
|
||||
ts: { type: 'number', description: 'Unix timestamp (milliseconds)' },
|
||||
},
|
||||
},
|
||||
cursor: {
|
||||
type: 'string',
|
||||
description: 'Pagination cursor for fetching more results',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -58,3 +58,219 @@ export const kalshiGetMarketTool: ToolConfig<KalshiGetMarketParams, KalshiGetMar
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 Get Market Tool - Returns exact Kalshi API response structure
|
||||
*/
|
||||
export interface KalshiGetMarketV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
market: {
|
||||
ticker: string
|
||||
event_ticker: string
|
||||
market_type: string
|
||||
title: string
|
||||
subtitle: string | null
|
||||
yes_sub_title: string | null
|
||||
no_sub_title: string | null
|
||||
open_time: string | null
|
||||
close_time: string | null
|
||||
expected_expiration_time: string | null
|
||||
expiration_time: string | null
|
||||
latest_expiration_time: string | null
|
||||
settlement_timer_seconds: number | null
|
||||
status: string
|
||||
response_price_units: string | null
|
||||
notional_value: number | null
|
||||
tick_size: number | null
|
||||
yes_bid: number | null
|
||||
yes_ask: number | null
|
||||
no_bid: number | null
|
||||
no_ask: number | null
|
||||
last_price: number | null
|
||||
previous_yes_bid: number | null
|
||||
previous_yes_ask: number | null
|
||||
previous_price: number | null
|
||||
volume: number | null
|
||||
volume_24h: number | null
|
||||
liquidity: number | null
|
||||
open_interest: number | null
|
||||
result: string | null
|
||||
cap_strike: number | null
|
||||
floor_strike: number | null
|
||||
can_close_early: boolean | null
|
||||
expiration_value: string | null
|
||||
category: string | null
|
||||
risk_limit_cents: number | null
|
||||
strike_type: string | null
|
||||
rules_primary: string | null
|
||||
rules_secondary: string | null
|
||||
settlement_source_url: string | null
|
||||
custom_strike: object | null
|
||||
underlying: string | null
|
||||
settlement_value: number | null
|
||||
cfd_contract_size: number | null
|
||||
yes_fee_fp: number | null
|
||||
no_fee_fp: number | null
|
||||
last_price_fp: number | null
|
||||
yes_bid_fp: number | null
|
||||
yes_ask_fp: number | null
|
||||
no_bid_fp: number | null
|
||||
no_ask_fp: number | null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const kalshiGetMarketV2Tool: ToolConfig<KalshiGetMarketParams, KalshiGetMarketV2Response> = {
|
||||
id: 'kalshi_get_market_v2',
|
||||
name: 'Get Market from Kalshi V2',
|
||||
description:
|
||||
'Retrieve details of a specific prediction market by ticker (V2 - full API response)',
|
||||
version: '2.0.0',
|
||||
|
||||
params: {
|
||||
ticker: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The market ticker (e.g., "KXBTC-24DEC31")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => buildKalshiUrl(`/markets/${params.ticker}`),
|
||||
method: 'GET',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handleKalshiError(data, response.status, 'get_market_v2')
|
||||
}
|
||||
|
||||
const m = data.market || {}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
market: {
|
||||
ticker: m.ticker ?? null,
|
||||
event_ticker: m.event_ticker ?? null,
|
||||
market_type: m.market_type ?? null,
|
||||
title: m.title ?? null,
|
||||
subtitle: m.subtitle ?? null,
|
||||
yes_sub_title: m.yes_sub_title ?? null,
|
||||
no_sub_title: m.no_sub_title ?? null,
|
||||
open_time: m.open_time ?? null,
|
||||
close_time: m.close_time ?? null,
|
||||
expected_expiration_time: m.expected_expiration_time ?? null,
|
||||
expiration_time: m.expiration_time ?? null,
|
||||
latest_expiration_time: m.latest_expiration_time ?? null,
|
||||
settlement_timer_seconds: m.settlement_timer_seconds ?? null,
|
||||
status: m.status ?? null,
|
||||
response_price_units: m.response_price_units ?? null,
|
||||
notional_value: m.notional_value ?? null,
|
||||
tick_size: m.tick_size ?? null,
|
||||
yes_bid: m.yes_bid ?? null,
|
||||
yes_ask: m.yes_ask ?? null,
|
||||
no_bid: m.no_bid ?? null,
|
||||
no_ask: m.no_ask ?? null,
|
||||
last_price: m.last_price ?? null,
|
||||
previous_yes_bid: m.previous_yes_bid ?? null,
|
||||
previous_yes_ask: m.previous_yes_ask ?? null,
|
||||
previous_price: m.previous_price ?? null,
|
||||
volume: m.volume ?? null,
|
||||
volume_24h: m.volume_24h ?? null,
|
||||
liquidity: m.liquidity ?? null,
|
||||
open_interest: m.open_interest ?? null,
|
||||
result: m.result ?? null,
|
||||
cap_strike: m.cap_strike ?? null,
|
||||
floor_strike: m.floor_strike ?? null,
|
||||
can_close_early: m.can_close_early ?? null,
|
||||
expiration_value: m.expiration_value ?? null,
|
||||
category: m.category ?? null,
|
||||
risk_limit_cents: m.risk_limit_cents ?? null,
|
||||
strike_type: m.strike_type ?? null,
|
||||
rules_primary: m.rules_primary ?? null,
|
||||
rules_secondary: m.rules_secondary ?? null,
|
||||
settlement_source_url: m.settlement_source_url ?? null,
|
||||
custom_strike: m.custom_strike ?? null,
|
||||
underlying: m.underlying ?? null,
|
||||
settlement_value: m.settlement_value ?? null,
|
||||
cfd_contract_size: m.cfd_contract_size ?? null,
|
||||
yes_fee_fp: m.yes_fee_fp ?? null,
|
||||
no_fee_fp: m.no_fee_fp ?? null,
|
||||
last_price_fp: m.last_price_fp ?? null,
|
||||
yes_bid_fp: m.yes_bid_fp ?? null,
|
||||
yes_ask_fp: m.yes_ask_fp ?? null,
|
||||
no_bid_fp: m.no_bid_fp ?? null,
|
||||
no_ask_fp: m.no_ask_fp ?? null,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
market: {
|
||||
type: 'object',
|
||||
description: 'Market object with all API fields',
|
||||
properties: {
|
||||
ticker: { type: 'string', description: 'Market ticker' },
|
||||
event_ticker: { type: 'string', description: 'Event ticker' },
|
||||
market_type: { type: 'string', description: 'Market type' },
|
||||
title: { type: 'string', description: 'Market title' },
|
||||
subtitle: { type: 'string', description: 'Market subtitle' },
|
||||
yes_sub_title: { type: 'string', description: 'Yes outcome subtitle' },
|
||||
no_sub_title: { type: 'string', description: 'No outcome subtitle' },
|
||||
open_time: { type: 'string', description: 'Market open time' },
|
||||
close_time: { type: 'string', description: 'Market close time' },
|
||||
expected_expiration_time: { type: 'string', description: 'Expected expiration time' },
|
||||
expiration_time: { type: 'string', description: 'Expiration time' },
|
||||
latest_expiration_time: { type: 'string', description: 'Latest expiration time' },
|
||||
settlement_timer_seconds: { type: 'number', description: 'Settlement timer in seconds' },
|
||||
status: { type: 'string', description: 'Market status' },
|
||||
response_price_units: { type: 'string', description: 'Response price units' },
|
||||
notional_value: { type: 'number', description: 'Notional value' },
|
||||
tick_size: { type: 'number', description: 'Tick size' },
|
||||
yes_bid: { type: 'number', description: 'Current yes bid price' },
|
||||
yes_ask: { type: 'number', description: 'Current yes ask price' },
|
||||
no_bid: { type: 'number', description: 'Current no bid price' },
|
||||
no_ask: { type: 'number', description: 'Current no ask price' },
|
||||
last_price: { type: 'number', description: 'Last trade price' },
|
||||
previous_yes_bid: { type: 'number', description: 'Previous yes bid' },
|
||||
previous_yes_ask: { type: 'number', description: 'Previous yes ask' },
|
||||
previous_price: { type: 'number', description: 'Previous price' },
|
||||
volume: { type: 'number', description: 'Total volume' },
|
||||
volume_24h: { type: 'number', description: '24-hour volume' },
|
||||
liquidity: { type: 'number', description: 'Market liquidity' },
|
||||
open_interest: { type: 'number', description: 'Open interest' },
|
||||
result: { type: 'string', description: 'Market result' },
|
||||
cap_strike: { type: 'number', description: 'Cap strike' },
|
||||
floor_strike: { type: 'number', description: 'Floor strike' },
|
||||
can_close_early: { type: 'boolean', description: 'Can close early' },
|
||||
expiration_value: { type: 'string', description: 'Expiration value' },
|
||||
category: { type: 'string', description: 'Market category' },
|
||||
risk_limit_cents: { type: 'number', description: 'Risk limit in cents' },
|
||||
strike_type: { type: 'string', description: 'Strike type' },
|
||||
rules_primary: { type: 'string', description: 'Primary rules' },
|
||||
rules_secondary: { type: 'string', description: 'Secondary rules' },
|
||||
settlement_source_url: { type: 'string', description: 'Settlement source URL' },
|
||||
custom_strike: { type: 'object', description: 'Custom strike object' },
|
||||
underlying: { type: 'string', description: 'Underlying asset' },
|
||||
settlement_value: { type: 'number', description: 'Settlement value' },
|
||||
cfd_contract_size: { type: 'number', description: 'CFD contract size' },
|
||||
yes_fee_fp: { type: 'number', description: 'Yes fee (fixed-point)' },
|
||||
no_fee_fp: { type: 'number', description: 'No fee (fixed-point)' },
|
||||
last_price_fp: { type: 'number', description: 'Last price (fixed-point)' },
|
||||
yes_bid_fp: { type: 'number', description: 'Yes bid (fixed-point)' },
|
||||
yes_ask_fp: { type: 'number', description: 'Yes ask (fixed-point)' },
|
||||
no_bid_fp: { type: 'number', description: 'No bid (fixed-point)' },
|
||||
no_ask_fp: { type: 'number', description: 'No ask (fixed-point)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -105,3 +105,341 @@ export const kalshiGetMarketsTool: ToolConfig<KalshiGetMarketsParams, KalshiGetM
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 Get Markets Tool - Returns exact Kalshi API response structure with all params
|
||||
*/
|
||||
export interface KalshiGetMarketsV2Params extends KalshiPaginationParams {
|
||||
status?: string // unopened, open, closed, settled
|
||||
seriesTicker?: string
|
||||
eventTicker?: string
|
||||
minCreatedTs?: number
|
||||
maxCreatedTs?: number
|
||||
minUpdatedTs?: number
|
||||
minCloseTs?: number
|
||||
maxCloseTs?: number
|
||||
minSettledTs?: number
|
||||
maxSettledTs?: number
|
||||
tickers?: string // comma-separated list
|
||||
mveFilter?: string // display or all
|
||||
}
|
||||
|
||||
export interface KalshiGetMarketsV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
markets: Array<{
|
||||
ticker: string
|
||||
event_ticker: string
|
||||
market_type: string
|
||||
title: string
|
||||
subtitle: string | null
|
||||
yes_sub_title: string | null
|
||||
no_sub_title: string | null
|
||||
open_time: string | null
|
||||
close_time: string | null
|
||||
expected_expiration_time: string | null
|
||||
expiration_time: string | null
|
||||
latest_expiration_time: string | null
|
||||
settlement_timer_seconds: number | null
|
||||
status: string
|
||||
response_price_units: string | null
|
||||
notional_value: number | null
|
||||
tick_size: number | null
|
||||
yes_bid: number | null
|
||||
yes_ask: number | null
|
||||
no_bid: number | null
|
||||
no_ask: number | null
|
||||
last_price: number | null
|
||||
previous_yes_bid: number | null
|
||||
previous_yes_ask: number | null
|
||||
previous_price: number | null
|
||||
volume: number | null
|
||||
volume_24h: number | null
|
||||
liquidity: number | null
|
||||
open_interest: number | null
|
||||
result: string | null
|
||||
cap_strike: number | null
|
||||
floor_strike: number | null
|
||||
can_close_early: boolean | null
|
||||
expiration_value: string | null
|
||||
category: string | null
|
||||
risk_limit_cents: number | null
|
||||
strike_type: string | null
|
||||
rules_primary: string | null
|
||||
rules_secondary: string | null
|
||||
settlement_source_url: string | null
|
||||
custom_strike: object | null
|
||||
underlying: string | null
|
||||
settlement_value: number | null
|
||||
cfd_contract_size: number | null
|
||||
yes_fee_fp: number | null
|
||||
no_fee_fp: number | null
|
||||
last_price_fp: number | null
|
||||
yes_bid_fp: number | null
|
||||
yes_ask_fp: number | null
|
||||
no_bid_fp: number | null
|
||||
no_ask_fp: number | null
|
||||
}>
|
||||
cursor: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export const kalshiGetMarketsV2Tool: ToolConfig<
|
||||
KalshiGetMarketsV2Params,
|
||||
KalshiGetMarketsV2Response
|
||||
> = {
|
||||
id: 'kalshi_get_markets_v2',
|
||||
name: 'Get Markets from Kalshi V2',
|
||||
description:
|
||||
'Retrieve a list of prediction markets from Kalshi with all filtering options (V2 - full API response)',
|
||||
version: '2.0.0',
|
||||
|
||||
params: {
|
||||
status: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by status (unopened, open, closed, settled)',
|
||||
},
|
||||
seriesTicker: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by series ticker',
|
||||
},
|
||||
eventTicker: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by event ticker',
|
||||
},
|
||||
minCreatedTs: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Minimum created timestamp (Unix seconds)',
|
||||
},
|
||||
maxCreatedTs: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum created timestamp (Unix seconds)',
|
||||
},
|
||||
minUpdatedTs: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Minimum updated timestamp (Unix seconds)',
|
||||
},
|
||||
minCloseTs: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Minimum close timestamp (Unix seconds)',
|
||||
},
|
||||
maxCloseTs: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum close timestamp (Unix seconds)',
|
||||
},
|
||||
minSettledTs: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Minimum settled timestamp (Unix seconds)',
|
||||
},
|
||||
maxSettledTs: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum settled timestamp (Unix seconds)',
|
||||
},
|
||||
tickers: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Comma-separated list of tickers to filter',
|
||||
},
|
||||
mveFilter: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'MVE filter (display or all)',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of results (1-1000, default: 100)',
|
||||
},
|
||||
cursor: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination cursor for next page',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.status) queryParams.append('status', params.status)
|
||||
if (params.seriesTicker) queryParams.append('series_ticker', params.seriesTicker)
|
||||
if (params.eventTicker) queryParams.append('event_ticker', params.eventTicker)
|
||||
if (params.minCreatedTs) queryParams.append('min_created_ts', params.minCreatedTs.toString())
|
||||
if (params.maxCreatedTs) queryParams.append('max_created_ts', params.maxCreatedTs.toString())
|
||||
if (params.minUpdatedTs) queryParams.append('min_updated_ts', params.minUpdatedTs.toString())
|
||||
if (params.minCloseTs) queryParams.append('min_close_ts', params.minCloseTs.toString())
|
||||
if (params.maxCloseTs) queryParams.append('max_close_ts', params.maxCloseTs.toString())
|
||||
if (params.minSettledTs) queryParams.append('min_settled_ts', params.minSettledTs.toString())
|
||||
if (params.maxSettledTs) queryParams.append('max_settled_ts', params.maxSettledTs.toString())
|
||||
if (params.tickers) queryParams.append('tickers', params.tickers)
|
||||
if (params.mveFilter) queryParams.append('mve_filter', params.mveFilter)
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.cursor) queryParams.append('cursor', params.cursor)
|
||||
|
||||
const query = queryParams.toString()
|
||||
const url = buildKalshiUrl('/markets')
|
||||
return query ? `${url}?${query}` : url
|
||||
},
|
||||
method: 'GET',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handleKalshiError(data, response.status, 'get_markets_v2')
|
||||
}
|
||||
|
||||
const markets = (data.markets || []).map((m: Record<string, unknown>) => ({
|
||||
ticker: m.ticker ?? null,
|
||||
event_ticker: m.event_ticker ?? null,
|
||||
market_type: m.market_type ?? null,
|
||||
title: m.title ?? null,
|
||||
subtitle: m.subtitle ?? null,
|
||||
yes_sub_title: m.yes_sub_title ?? null,
|
||||
no_sub_title: m.no_sub_title ?? null,
|
||||
open_time: m.open_time ?? null,
|
||||
close_time: m.close_time ?? null,
|
||||
expected_expiration_time: m.expected_expiration_time ?? null,
|
||||
expiration_time: m.expiration_time ?? null,
|
||||
latest_expiration_time: m.latest_expiration_time ?? null,
|
||||
settlement_timer_seconds: m.settlement_timer_seconds ?? null,
|
||||
status: m.status ?? null,
|
||||
response_price_units: m.response_price_units ?? null,
|
||||
notional_value: m.notional_value ?? null,
|
||||
tick_size: m.tick_size ?? null,
|
||||
yes_bid: m.yes_bid ?? null,
|
||||
yes_ask: m.yes_ask ?? null,
|
||||
no_bid: m.no_bid ?? null,
|
||||
no_ask: m.no_ask ?? null,
|
||||
last_price: m.last_price ?? null,
|
||||
previous_yes_bid: m.previous_yes_bid ?? null,
|
||||
previous_yes_ask: m.previous_yes_ask ?? null,
|
||||
previous_price: m.previous_price ?? null,
|
||||
volume: m.volume ?? null,
|
||||
volume_24h: m.volume_24h ?? null,
|
||||
liquidity: m.liquidity ?? null,
|
||||
open_interest: m.open_interest ?? null,
|
||||
result: m.result ?? null,
|
||||
cap_strike: m.cap_strike ?? null,
|
||||
floor_strike: m.floor_strike ?? null,
|
||||
can_close_early: m.can_close_early ?? null,
|
||||
expiration_value: m.expiration_value ?? null,
|
||||
category: m.category ?? null,
|
||||
risk_limit_cents: m.risk_limit_cents ?? null,
|
||||
strike_type: m.strike_type ?? null,
|
||||
rules_primary: m.rules_primary ?? null,
|
||||
rules_secondary: m.rules_secondary ?? null,
|
||||
settlement_source_url: m.settlement_source_url ?? null,
|
||||
custom_strike: m.custom_strike ?? null,
|
||||
underlying: m.underlying ?? null,
|
||||
settlement_value: m.settlement_value ?? null,
|
||||
cfd_contract_size: m.cfd_contract_size ?? null,
|
||||
yes_fee_fp: m.yes_fee_fp ?? null,
|
||||
no_fee_fp: m.no_fee_fp ?? null,
|
||||
last_price_fp: m.last_price_fp ?? null,
|
||||
yes_bid_fp: m.yes_bid_fp ?? null,
|
||||
yes_ask_fp: m.yes_ask_fp ?? null,
|
||||
no_bid_fp: m.no_bid_fp ?? null,
|
||||
no_ask_fp: m.no_ask_fp ?? null,
|
||||
}))
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
markets,
|
||||
cursor: data.cursor ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
markets: {
|
||||
type: 'array',
|
||||
description: 'Array of market objects with all API fields',
|
||||
properties: {
|
||||
ticker: { type: 'string', description: 'Market ticker' },
|
||||
event_ticker: { type: 'string', description: 'Event ticker' },
|
||||
market_type: { type: 'string', description: 'Market type' },
|
||||
title: { type: 'string', description: 'Market title' },
|
||||
subtitle: { type: 'string', description: 'Market subtitle' },
|
||||
yes_sub_title: { type: 'string', description: 'Yes outcome subtitle' },
|
||||
no_sub_title: { type: 'string', description: 'No outcome subtitle' },
|
||||
open_time: { type: 'string', description: 'Market open time' },
|
||||
close_time: { type: 'string', description: 'Market close time' },
|
||||
expected_expiration_time: { type: 'string', description: 'Expected expiration time' },
|
||||
expiration_time: { type: 'string', description: 'Expiration time' },
|
||||
latest_expiration_time: { type: 'string', description: 'Latest expiration time' },
|
||||
settlement_timer_seconds: { type: 'number', description: 'Settlement timer in seconds' },
|
||||
status: { type: 'string', description: 'Market status' },
|
||||
response_price_units: { type: 'string', description: 'Response price units' },
|
||||
notional_value: { type: 'number', description: 'Notional value' },
|
||||
tick_size: { type: 'number', description: 'Tick size' },
|
||||
yes_bid: { type: 'number', description: 'Current yes bid price' },
|
||||
yes_ask: { type: 'number', description: 'Current yes ask price' },
|
||||
no_bid: { type: 'number', description: 'Current no bid price' },
|
||||
no_ask: { type: 'number', description: 'Current no ask price' },
|
||||
last_price: { type: 'number', description: 'Last trade price' },
|
||||
previous_yes_bid: { type: 'number', description: 'Previous yes bid' },
|
||||
previous_yes_ask: { type: 'number', description: 'Previous yes ask' },
|
||||
previous_price: { type: 'number', description: 'Previous price' },
|
||||
volume: { type: 'number', description: 'Total volume' },
|
||||
volume_24h: { type: 'number', description: '24-hour volume' },
|
||||
liquidity: { type: 'number', description: 'Market liquidity' },
|
||||
open_interest: { type: 'number', description: 'Open interest' },
|
||||
result: { type: 'string', description: 'Market result' },
|
||||
cap_strike: { type: 'number', description: 'Cap strike' },
|
||||
floor_strike: { type: 'number', description: 'Floor strike' },
|
||||
can_close_early: { type: 'boolean', description: 'Can close early' },
|
||||
expiration_value: { type: 'string', description: 'Expiration value' },
|
||||
category: { type: 'string', description: 'Market category' },
|
||||
risk_limit_cents: { type: 'number', description: 'Risk limit in cents' },
|
||||
strike_type: { type: 'string', description: 'Strike type' },
|
||||
rules_primary: { type: 'string', description: 'Primary rules' },
|
||||
rules_secondary: { type: 'string', description: 'Secondary rules' },
|
||||
settlement_source_url: { type: 'string', description: 'Settlement source URL' },
|
||||
custom_strike: { type: 'object', description: 'Custom strike object' },
|
||||
underlying: { type: 'string', description: 'Underlying asset' },
|
||||
settlement_value: { type: 'number', description: 'Settlement value' },
|
||||
cfd_contract_size: { type: 'number', description: 'CFD contract size' },
|
||||
yes_fee_fp: { type: 'number', description: 'Yes fee (fixed-point)' },
|
||||
no_fee_fp: { type: 'number', description: 'No fee (fixed-point)' },
|
||||
last_price_fp: { type: 'number', description: 'Last price (fixed-point)' },
|
||||
yes_bid_fp: { type: 'number', description: 'Yes bid (fixed-point)' },
|
||||
yes_ask_fp: { type: 'number', description: 'Yes ask (fixed-point)' },
|
||||
no_bid_fp: { type: 'number', description: 'No bid (fixed-point)' },
|
||||
no_ask_fp: { type: 'number', description: 'No ask (fixed-point)' },
|
||||
},
|
||||
},
|
||||
cursor: {
|
||||
type: 'string',
|
||||
description: 'Pagination cursor for fetching more results',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -71,3 +71,178 @@ export const kalshiGetOrderTool: ToolConfig<KalshiGetOrderParams, KalshiGetOrder
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export interface KalshiGetOrderV2Params extends KalshiAuthParams {
|
||||
orderId: string // Order ID to retrieve (required)
|
||||
}
|
||||
|
||||
export interface KalshiGetOrderV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
order: {
|
||||
order_id: string
|
||||
user_id: string | null
|
||||
client_order_id: string | null
|
||||
ticker: string
|
||||
side: string
|
||||
action: string
|
||||
type: string
|
||||
status: string
|
||||
yes_price: number | null
|
||||
no_price: number | null
|
||||
yes_price_dollars: string | null
|
||||
no_price_dollars: string | null
|
||||
fill_count: number | null
|
||||
fill_count_fp: string | null
|
||||
remaining_count: number | null
|
||||
remaining_count_fp: string | null
|
||||
initial_count: number | null
|
||||
initial_count_fp: string | null
|
||||
taker_fees: number | null
|
||||
maker_fees: number | null
|
||||
taker_fees_dollars: string | null
|
||||
maker_fees_dollars: string | null
|
||||
taker_fill_cost: number | null
|
||||
maker_fill_cost: number | null
|
||||
taker_fill_cost_dollars: string | null
|
||||
maker_fill_cost_dollars: string | null
|
||||
queue_position: number | null
|
||||
expiration_time: string | null
|
||||
created_time: string | null
|
||||
last_update_time: string | null
|
||||
self_trade_prevention_type: string | null
|
||||
order_group_id: string | null
|
||||
cancel_order_on_pause: boolean | null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const kalshiGetOrderV2Tool: ToolConfig<KalshiGetOrderV2Params, KalshiGetOrderV2Response> = {
|
||||
id: 'kalshi_get_order_v2',
|
||||
name: 'Get Order from Kalshi V2',
|
||||
description: 'Retrieve details of a specific order by ID from Kalshi (V2 with full API response)',
|
||||
version: '2.0.0',
|
||||
|
||||
params: {
|
||||
keyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your Kalshi API Key ID',
|
||||
},
|
||||
privateKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your RSA Private Key (PEM format)',
|
||||
},
|
||||
orderId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The order ID to retrieve',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => buildKalshiUrl(`/portfolio/orders/${params.orderId}`),
|
||||
method: 'GET',
|
||||
headers: (params) => {
|
||||
const path = `/trade-api/v2/portfolio/orders/${params.orderId}`
|
||||
return buildKalshiAuthHeaders(params.keyId, params.privateKey, 'GET', path)
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handleKalshiError(data, response.status, 'get_order_v2')
|
||||
}
|
||||
|
||||
const order = data.order || {}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
order: {
|
||||
order_id: order.order_id ?? null,
|
||||
user_id: order.user_id ?? null,
|
||||
client_order_id: order.client_order_id ?? null,
|
||||
ticker: order.ticker ?? null,
|
||||
side: order.side ?? null,
|
||||
action: order.action ?? null,
|
||||
type: order.type ?? null,
|
||||
status: order.status ?? null,
|
||||
yes_price: order.yes_price ?? null,
|
||||
no_price: order.no_price ?? null,
|
||||
yes_price_dollars: order.yes_price_dollars ?? null,
|
||||
no_price_dollars: order.no_price_dollars ?? null,
|
||||
fill_count: order.fill_count ?? null,
|
||||
fill_count_fp: order.fill_count_fp ?? null,
|
||||
remaining_count: order.remaining_count ?? null,
|
||||
remaining_count_fp: order.remaining_count_fp ?? null,
|
||||
initial_count: order.initial_count ?? null,
|
||||
initial_count_fp: order.initial_count_fp ?? null,
|
||||
taker_fees: order.taker_fees ?? null,
|
||||
maker_fees: order.maker_fees ?? null,
|
||||
taker_fees_dollars: order.taker_fees_dollars ?? null,
|
||||
maker_fees_dollars: order.maker_fees_dollars ?? null,
|
||||
taker_fill_cost: order.taker_fill_cost ?? null,
|
||||
maker_fill_cost: order.maker_fill_cost ?? null,
|
||||
taker_fill_cost_dollars: order.taker_fill_cost_dollars ?? null,
|
||||
maker_fill_cost_dollars: order.maker_fill_cost_dollars ?? null,
|
||||
queue_position: order.queue_position ?? null,
|
||||
expiration_time: order.expiration_time ?? null,
|
||||
created_time: order.created_time ?? null,
|
||||
last_update_time: order.last_update_time ?? null,
|
||||
self_trade_prevention_type: order.self_trade_prevention_type ?? null,
|
||||
order_group_id: order.order_group_id ?? null,
|
||||
cancel_order_on_pause: order.cancel_order_on_pause ?? null,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
order: {
|
||||
type: 'object',
|
||||
description: 'Order object with full API response fields',
|
||||
properties: {
|
||||
order_id: { type: 'string', description: 'Order ID' },
|
||||
user_id: { type: 'string', description: 'User ID' },
|
||||
client_order_id: { type: 'string', description: 'Client order ID' },
|
||||
ticker: { type: 'string', description: 'Market ticker' },
|
||||
side: { type: 'string', description: 'Order side (yes/no)' },
|
||||
action: { type: 'string', description: 'Action (buy/sell)' },
|
||||
type: { type: 'string', description: 'Order type (limit/market)' },
|
||||
status: { type: 'string', description: 'Order status (resting/canceled/executed)' },
|
||||
yes_price: { type: 'number', description: 'Yes price in cents' },
|
||||
no_price: { type: 'number', description: 'No price in cents' },
|
||||
yes_price_dollars: { type: 'string', description: 'Yes price in dollars' },
|
||||
no_price_dollars: { type: 'string', description: 'No price in dollars' },
|
||||
fill_count: { type: 'number', description: 'Filled contract count' },
|
||||
fill_count_fp: { type: 'string', description: 'Filled count (fixed-point)' },
|
||||
remaining_count: { type: 'number', description: 'Remaining contracts' },
|
||||
remaining_count_fp: { type: 'string', description: 'Remaining count (fixed-point)' },
|
||||
initial_count: { type: 'number', description: 'Initial contract count' },
|
||||
initial_count_fp: { type: 'string', description: 'Initial count (fixed-point)' },
|
||||
taker_fees: { type: 'number', description: 'Taker fees in cents' },
|
||||
maker_fees: { type: 'number', description: 'Maker fees in cents' },
|
||||
taker_fees_dollars: { type: 'string', description: 'Taker fees in dollars' },
|
||||
maker_fees_dollars: { type: 'string', description: 'Maker fees in dollars' },
|
||||
taker_fill_cost: { type: 'number', description: 'Taker fill cost in cents' },
|
||||
maker_fill_cost: { type: 'number', description: 'Maker fill cost in cents' },
|
||||
taker_fill_cost_dollars: { type: 'string', description: 'Taker fill cost in dollars' },
|
||||
maker_fill_cost_dollars: { type: 'string', description: 'Maker fill cost in dollars' },
|
||||
queue_position: { type: 'number', description: 'Queue position (deprecated)' },
|
||||
expiration_time: { type: 'string', description: 'Order expiration time' },
|
||||
created_time: { type: 'string', description: 'Order creation time' },
|
||||
last_update_time: { type: 'string', description: 'Last update time' },
|
||||
self_trade_prevention_type: { type: 'string', description: 'Self-trade prevention type' },
|
||||
order_group_id: { type: 'string', description: 'Order group ID' },
|
||||
cancel_order_on_pause: { type: 'boolean', description: 'Cancel on market pause' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -63,3 +63,135 @@ export const kalshiGetOrderbookTool: ToolConfig<
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 Get Orderbook Tool - Returns exact Kalshi API response structure with depth param
|
||||
* API returns tuple arrays: [price, count] for orderbook, [dollars_string, count] for _dollars variants
|
||||
*/
|
||||
export interface KalshiGetOrderbookV2Params {
|
||||
ticker: string
|
||||
depth?: number // Number of price levels to return
|
||||
}
|
||||
|
||||
export interface KalshiGetOrderbookV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
orderbook: {
|
||||
yes: Array<[number, number]> // [price_in_cents, count]
|
||||
no: Array<[number, number]> // [price_in_cents, count]
|
||||
yes_dollars: Array<[string, number]> // [dollars_string, count]
|
||||
no_dollars: Array<[string, number]> // [dollars_string, count]
|
||||
}
|
||||
orderbook_fp: {
|
||||
yes_dollars: Array<[string, string]> // [dollars_string, fp_count_string]
|
||||
no_dollars: Array<[string, string]> // [dollars_string, fp_count_string]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const kalshiGetOrderbookV2Tool: ToolConfig<
|
||||
KalshiGetOrderbookV2Params,
|
||||
KalshiGetOrderbookV2Response
|
||||
> = {
|
||||
id: 'kalshi_get_orderbook_v2',
|
||||
name: 'Get Market Orderbook from Kalshi V2',
|
||||
description:
|
||||
'Retrieve the orderbook (yes and no bids) for a specific market (V2 - includes depth and fp fields)',
|
||||
version: '2.0.0',
|
||||
|
||||
params: {
|
||||
ticker: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Market ticker (e.g., KXBTC-24DEC31)',
|
||||
},
|
||||
depth: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of price levels to return (default: all)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.depth) queryParams.append('depth', params.depth.toString())
|
||||
|
||||
const query = queryParams.toString()
|
||||
const url = buildKalshiUrl(`/markets/${params.ticker}/orderbook`)
|
||||
return query ? `${url}?${query}` : url
|
||||
},
|
||||
method: 'GET',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handleKalshiError(data, response.status, 'get_orderbook_v2')
|
||||
}
|
||||
|
||||
const orderbook = data.orderbook || {}
|
||||
const orderbookFp = data.orderbook_fp || {}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
orderbook: {
|
||||
yes: orderbook.yes ?? [],
|
||||
no: orderbook.no ?? [],
|
||||
yes_dollars: orderbook.yes_dollars ?? [],
|
||||
no_dollars: orderbook.no_dollars ?? [],
|
||||
},
|
||||
orderbook_fp: {
|
||||
yes_dollars: orderbookFp.yes_dollars ?? [],
|
||||
no_dollars: orderbookFp.no_dollars ?? [],
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
orderbook: {
|
||||
type: 'object',
|
||||
description: 'Orderbook with yes/no bids (legacy integer counts)',
|
||||
properties: {
|
||||
yes: {
|
||||
type: 'array',
|
||||
description: 'Yes side bids as tuples [price_cents, count]',
|
||||
},
|
||||
no: {
|
||||
type: 'array',
|
||||
description: 'No side bids as tuples [price_cents, count]',
|
||||
},
|
||||
yes_dollars: {
|
||||
type: 'array',
|
||||
description: 'Yes side bids as tuples [dollars_string, count]',
|
||||
},
|
||||
no_dollars: {
|
||||
type: 'array',
|
||||
description: 'No side bids as tuples [dollars_string, count]',
|
||||
},
|
||||
},
|
||||
},
|
||||
orderbook_fp: {
|
||||
type: 'object',
|
||||
description: 'Orderbook with fixed-point counts (preferred)',
|
||||
properties: {
|
||||
yes_dollars: {
|
||||
type: 'array',
|
||||
description: 'Yes side bids as tuples [dollars_string, fp_count_string]',
|
||||
},
|
||||
no_dollars: {
|
||||
type: 'array',
|
||||
description: 'No side bids as tuples [dollars_string, fp_count_string]',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -123,3 +123,250 @@ export const kalshiGetOrdersTool: ToolConfig<KalshiGetOrdersParams, KalshiGetOrd
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export interface KalshiGetOrdersV2Params extends KalshiAuthParams, KalshiPaginationParams {
|
||||
ticker?: string
|
||||
eventTicker?: string
|
||||
status?: string // resting, canceled, executed
|
||||
minTs?: string // Minimum timestamp filter (Unix timestamp)
|
||||
maxTs?: string // Maximum timestamp filter (Unix timestamp)
|
||||
subaccount?: string // Subaccount to filter orders
|
||||
}
|
||||
|
||||
export interface KalshiOrderV2 {
|
||||
order_id: string
|
||||
user_id: string | null
|
||||
client_order_id: string | null
|
||||
ticker: string
|
||||
side: string
|
||||
action: string
|
||||
type: string
|
||||
status: string
|
||||
yes_price: number | null
|
||||
no_price: number | null
|
||||
yes_price_dollars: string | null
|
||||
no_price_dollars: string | null
|
||||
fill_count: number | null
|
||||
fill_count_fp: string | null
|
||||
remaining_count: number | null
|
||||
remaining_count_fp: string | null
|
||||
initial_count: number | null
|
||||
initial_count_fp: string | null
|
||||
taker_fees: number | null
|
||||
maker_fees: number | null
|
||||
taker_fees_dollars: string | null
|
||||
maker_fees_dollars: string | null
|
||||
taker_fill_cost: number | null
|
||||
maker_fill_cost: number | null
|
||||
taker_fill_cost_dollars: string | null
|
||||
maker_fill_cost_dollars: string | null
|
||||
queue_position: number | null
|
||||
expiration_time: string | null
|
||||
created_time: string | null
|
||||
last_update_time: string | null
|
||||
self_trade_prevention_type: string | null
|
||||
order_group_id: string | null
|
||||
cancel_order_on_pause: boolean | null
|
||||
}
|
||||
|
||||
export interface KalshiGetOrdersV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
orders: KalshiOrderV2[]
|
||||
cursor: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export const kalshiGetOrdersV2Tool: ToolConfig<KalshiGetOrdersV2Params, KalshiGetOrdersV2Response> =
|
||||
{
|
||||
id: 'kalshi_get_orders_v2',
|
||||
name: 'Get Orders from Kalshi V2',
|
||||
description:
|
||||
'Retrieve your orders from Kalshi with optional filtering (V2 with full API response)',
|
||||
version: '2.0.0',
|
||||
|
||||
params: {
|
||||
keyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your Kalshi API Key ID',
|
||||
},
|
||||
privateKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your RSA Private Key (PEM format)',
|
||||
},
|
||||
ticker: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by market ticker',
|
||||
},
|
||||
eventTicker: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by event ticker (max 10 comma-separated)',
|
||||
},
|
||||
status: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by status (resting, canceled, executed)',
|
||||
},
|
||||
minTs: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Minimum timestamp filter (Unix timestamp)',
|
||||
},
|
||||
maxTs: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum timestamp filter (Unix timestamp)',
|
||||
},
|
||||
subaccount: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Subaccount to filter orders',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of results (1-200, default: 100)',
|
||||
},
|
||||
cursor: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination cursor for next page',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.ticker) queryParams.append('ticker', params.ticker)
|
||||
if (params.eventTicker) queryParams.append('event_ticker', params.eventTicker)
|
||||
if (params.status) queryParams.append('status', params.status)
|
||||
if (params.minTs) queryParams.append('min_ts', params.minTs)
|
||||
if (params.maxTs) queryParams.append('max_ts', params.maxTs)
|
||||
if (params.subaccount) queryParams.append('subaccount', params.subaccount)
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.cursor) queryParams.append('cursor', params.cursor)
|
||||
|
||||
const query = queryParams.toString()
|
||||
const url = buildKalshiUrl('/portfolio/orders')
|
||||
return query ? `${url}?${query}` : url
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => {
|
||||
const path = '/trade-api/v2/portfolio/orders'
|
||||
return buildKalshiAuthHeaders(params.keyId, params.privateKey, 'GET', path)
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handleKalshiError(data, response.status, 'get_orders_v2')
|
||||
}
|
||||
|
||||
const rawOrders = data.orders || []
|
||||
const orders: KalshiOrderV2[] = rawOrders.map((order: any) => ({
|
||||
order_id: order.order_id ?? null,
|
||||
user_id: order.user_id ?? null,
|
||||
client_order_id: order.client_order_id ?? null,
|
||||
ticker: order.ticker ?? null,
|
||||
side: order.side ?? null,
|
||||
action: order.action ?? null,
|
||||
type: order.type ?? null,
|
||||
status: order.status ?? null,
|
||||
yes_price: order.yes_price ?? null,
|
||||
no_price: order.no_price ?? null,
|
||||
yes_price_dollars: order.yes_price_dollars ?? null,
|
||||
no_price_dollars: order.no_price_dollars ?? null,
|
||||
fill_count: order.fill_count ?? null,
|
||||
fill_count_fp: order.fill_count_fp ?? null,
|
||||
remaining_count: order.remaining_count ?? null,
|
||||
remaining_count_fp: order.remaining_count_fp ?? null,
|
||||
initial_count: order.initial_count ?? null,
|
||||
initial_count_fp: order.initial_count_fp ?? null,
|
||||
taker_fees: order.taker_fees ?? null,
|
||||
maker_fees: order.maker_fees ?? null,
|
||||
taker_fees_dollars: order.taker_fees_dollars ?? null,
|
||||
maker_fees_dollars: order.maker_fees_dollars ?? null,
|
||||
taker_fill_cost: order.taker_fill_cost ?? null,
|
||||
maker_fill_cost: order.maker_fill_cost ?? null,
|
||||
taker_fill_cost_dollars: order.taker_fill_cost_dollars ?? null,
|
||||
maker_fill_cost_dollars: order.maker_fill_cost_dollars ?? null,
|
||||
queue_position: order.queue_position ?? null,
|
||||
expiration_time: order.expiration_time ?? null,
|
||||
created_time: order.created_time ?? null,
|
||||
last_update_time: order.last_update_time ?? null,
|
||||
self_trade_prevention_type: order.self_trade_prevention_type ?? null,
|
||||
order_group_id: order.order_group_id ?? null,
|
||||
cancel_order_on_pause: order.cancel_order_on_pause ?? null,
|
||||
}))
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
orders,
|
||||
cursor: data.cursor ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
orders: {
|
||||
type: 'array',
|
||||
description: 'Array of order objects with full API response fields',
|
||||
properties: {
|
||||
order_id: { type: 'string', description: 'Order ID' },
|
||||
user_id: { type: 'string', description: 'User ID' },
|
||||
client_order_id: { type: 'string', description: 'Client order ID' },
|
||||
ticker: { type: 'string', description: 'Market ticker' },
|
||||
side: { type: 'string', description: 'Order side (yes/no)' },
|
||||
action: { type: 'string', description: 'Action (buy/sell)' },
|
||||
type: { type: 'string', description: 'Order type (limit/market)' },
|
||||
status: { type: 'string', description: 'Order status (resting/canceled/executed)' },
|
||||
yes_price: { type: 'number', description: 'Yes price in cents' },
|
||||
no_price: { type: 'number', description: 'No price in cents' },
|
||||
yes_price_dollars: { type: 'string', description: 'Yes price in dollars' },
|
||||
no_price_dollars: { type: 'string', description: 'No price in dollars' },
|
||||
fill_count: { type: 'number', description: 'Filled contract count' },
|
||||
fill_count_fp: { type: 'string', description: 'Filled count (fixed-point)' },
|
||||
remaining_count: { type: 'number', description: 'Remaining contracts' },
|
||||
remaining_count_fp: { type: 'string', description: 'Remaining count (fixed-point)' },
|
||||
initial_count: { type: 'number', description: 'Initial contract count' },
|
||||
initial_count_fp: { type: 'string', description: 'Initial count (fixed-point)' },
|
||||
taker_fees: { type: 'number', description: 'Taker fees in cents' },
|
||||
maker_fees: { type: 'number', description: 'Maker fees in cents' },
|
||||
taker_fees_dollars: { type: 'string', description: 'Taker fees in dollars' },
|
||||
maker_fees_dollars: { type: 'string', description: 'Maker fees in dollars' },
|
||||
taker_fill_cost: { type: 'number', description: 'Taker fill cost in cents' },
|
||||
maker_fill_cost: { type: 'number', description: 'Maker fill cost in cents' },
|
||||
taker_fill_cost_dollars: { type: 'string', description: 'Taker fill cost in dollars' },
|
||||
maker_fill_cost_dollars: { type: 'string', description: 'Maker fill cost in dollars' },
|
||||
queue_position: { type: 'number', description: 'Queue position (deprecated)' },
|
||||
expiration_time: { type: 'string', description: 'Order expiration time' },
|
||||
created_time: { type: 'string', description: 'Order creation time' },
|
||||
last_update_time: { type: 'string', description: 'Last update time' },
|
||||
self_trade_prevention_type: { type: 'string', description: 'Self-trade prevention type' },
|
||||
order_group_id: { type: 'string', description: 'Order group ID' },
|
||||
cancel_order_on_pause: { type: 'boolean', description: 'Cancel on market pause' },
|
||||
},
|
||||
},
|
||||
cursor: {
|
||||
type: 'string',
|
||||
description: 'Pagination cursor for fetching more results',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -126,3 +126,195 @@ export const kalshiGetPositionsTool: ToolConfig<
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 Params for Get Positions - removes invalid settlementStatus, adds countFilter and subaccount
|
||||
*/
|
||||
export interface KalshiGetPositionsV2Params extends KalshiAuthParams, KalshiPaginationParams {
|
||||
ticker?: string
|
||||
eventTicker?: string
|
||||
countFilter?: string
|
||||
subaccount?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 Response matching Kalshi API exactly
|
||||
*/
|
||||
export interface KalshiGetPositionsV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
market_positions: Array<{
|
||||
ticker: string
|
||||
event_ticker: string
|
||||
event_title: string | null
|
||||
market_title: string | null
|
||||
position: number
|
||||
market_exposure: number | null
|
||||
realized_pnl: number | null
|
||||
total_traded: number | null
|
||||
resting_orders_count: number | null
|
||||
fees_paid: number | null
|
||||
}>
|
||||
event_positions: Array<{
|
||||
event_ticker: string
|
||||
event_exposure: number
|
||||
realized_pnl: number | null
|
||||
total_cost: number | null
|
||||
}> | null
|
||||
cursor: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export const kalshiGetPositionsV2Tool: ToolConfig<
|
||||
KalshiGetPositionsV2Params,
|
||||
KalshiGetPositionsV2Response
|
||||
> = {
|
||||
id: 'kalshi_get_positions_v2',
|
||||
name: 'Get Positions from Kalshi V2',
|
||||
description: 'Retrieve your open positions from Kalshi (V2 - exact API response)',
|
||||
version: '2.0.0',
|
||||
|
||||
params: {
|
||||
keyId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your Kalshi API Key ID',
|
||||
},
|
||||
privateKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your RSA Private Key (PEM format)',
|
||||
},
|
||||
ticker: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by market ticker',
|
||||
},
|
||||
eventTicker: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by event ticker (max 10 comma-separated)',
|
||||
},
|
||||
countFilter: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by count (all, positive, negative). Default: all',
|
||||
},
|
||||
subaccount: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Subaccount to get positions for',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of results (1-1000, default: 100)',
|
||||
},
|
||||
cursor: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination cursor for next page',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.ticker) queryParams.append('ticker', params.ticker)
|
||||
if (params.eventTicker) queryParams.append('event_ticker', params.eventTicker)
|
||||
if (params.countFilter) queryParams.append('count_filter', params.countFilter)
|
||||
if (params.subaccount) queryParams.append('subaccount', params.subaccount)
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.cursor) queryParams.append('cursor', params.cursor)
|
||||
|
||||
const query = queryParams.toString()
|
||||
const url = buildKalshiUrl('/portfolio/positions')
|
||||
return query ? `${url}?${query}` : url
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => {
|
||||
const path = '/trade-api/v2/portfolio/positions'
|
||||
return buildKalshiAuthHeaders(params.keyId, params.privateKey, 'GET', path)
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handleKalshiError(data, response.status, 'get_positions_v2')
|
||||
}
|
||||
|
||||
const marketPositions = (data.market_positions || []).map((p: Record<string, unknown>) => ({
|
||||
ticker: p.ticker ?? null,
|
||||
event_ticker: p.event_ticker ?? null,
|
||||
event_title: p.event_title ?? null,
|
||||
market_title: p.market_title ?? null,
|
||||
position: p.position ?? 0,
|
||||
market_exposure: p.market_exposure ?? null,
|
||||
realized_pnl: p.realized_pnl ?? null,
|
||||
total_traded: p.total_traded ?? null,
|
||||
resting_orders_count: p.resting_orders_count ?? null,
|
||||
fees_paid: p.fees_paid ?? null,
|
||||
}))
|
||||
|
||||
const eventPositions = data.event_positions
|
||||
? (data.event_positions as Array<Record<string, unknown>>).map((p) => ({
|
||||
event_ticker: (p.event_ticker as string) ?? '',
|
||||
event_exposure: (p.event_exposure as number) ?? 0,
|
||||
realized_pnl: (p.realized_pnl as number | null) ?? null,
|
||||
total_cost: (p.total_cost as number | null) ?? null,
|
||||
}))
|
||||
: null
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
market_positions: marketPositions,
|
||||
event_positions: eventPositions,
|
||||
cursor: data.cursor ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
market_positions: {
|
||||
type: 'array',
|
||||
description: 'Array of market position objects',
|
||||
properties: {
|
||||
ticker: { type: 'string', description: 'Market ticker' },
|
||||
event_ticker: { type: 'string', description: 'Event ticker' },
|
||||
event_title: { type: 'string', description: 'Event title' },
|
||||
market_title: { type: 'string', description: 'Market title' },
|
||||
position: { type: 'number', description: 'Position size' },
|
||||
market_exposure: { type: 'number', description: 'Market exposure' },
|
||||
realized_pnl: { type: 'number', description: 'Realized P&L' },
|
||||
total_traded: { type: 'number', description: 'Total traded' },
|
||||
resting_orders_count: { type: 'number', description: 'Resting orders count' },
|
||||
fees_paid: { type: 'number', description: 'Fees paid' },
|
||||
},
|
||||
},
|
||||
event_positions: {
|
||||
type: 'array',
|
||||
description: 'Array of event position objects',
|
||||
properties: {
|
||||
event_ticker: { type: 'string', description: 'Event ticker' },
|
||||
event_exposure: { type: 'number', description: 'Event exposure' },
|
||||
realized_pnl: { type: 'number', description: 'Realized P&L' },
|
||||
total_cost: { type: 'number', description: 'Total cost' },
|
||||
},
|
||||
},
|
||||
cursor: {
|
||||
type: 'string',
|
||||
description: 'Pagination cursor for fetching more results',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -65,3 +65,141 @@ export const kalshiGetSeriesByTickerTool: ToolConfig<
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 Params for Get Series by Ticker
|
||||
*/
|
||||
export interface KalshiGetSeriesByTickerV2Params {
|
||||
seriesTicker: string
|
||||
includeVolume?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 Response matching Kalshi API exactly
|
||||
*/
|
||||
export interface KalshiGetSeriesByTickerV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
series: {
|
||||
ticker: string
|
||||
title: string
|
||||
frequency: string
|
||||
category: string
|
||||
tags: string[] | null
|
||||
settlement_sources: Array<{
|
||||
name: string
|
||||
url: string
|
||||
}> | null
|
||||
contract_url: string | null
|
||||
contract_terms_url: string | null
|
||||
fee_type: string | null
|
||||
fee_multiplier: number | null
|
||||
additional_prohibitions: string[] | null
|
||||
product_metadata: Record<string, unknown> | null
|
||||
volume: number | null
|
||||
volume_fp: number | null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const kalshiGetSeriesByTickerV2Tool: ToolConfig<
|
||||
KalshiGetSeriesByTickerV2Params,
|
||||
KalshiGetSeriesByTickerV2Response
|
||||
> = {
|
||||
id: 'kalshi_get_series_by_ticker_v2',
|
||||
name: 'Get Series by Ticker from Kalshi V2',
|
||||
description: 'Retrieve details of a specific market series by ticker (V2 - exact API response)',
|
||||
version: '2.0.0',
|
||||
|
||||
params: {
|
||||
seriesTicker: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Series ticker',
|
||||
},
|
||||
includeVolume: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Include volume data in response (true/false)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.includeVolume) queryParams.append('include_volume', params.includeVolume)
|
||||
|
||||
const query = queryParams.toString()
|
||||
const url = buildKalshiUrl(`/series/${params.seriesTicker}`)
|
||||
return query ? `${url}?${query}` : url
|
||||
},
|
||||
method: 'GET',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handleKalshiError(data, response.status, 'get_series_by_ticker_v2')
|
||||
}
|
||||
|
||||
const series = data.series || data
|
||||
|
||||
const settlementSources = series.settlement_sources
|
||||
? (series.settlement_sources as Array<Record<string, unknown>>).map((s) => ({
|
||||
name: (s.name as string) ?? null,
|
||||
url: (s.url as string) ?? null,
|
||||
}))
|
||||
: null
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
series: {
|
||||
ticker: series.ticker ?? null,
|
||||
title: series.title ?? null,
|
||||
frequency: series.frequency ?? null,
|
||||
category: series.category ?? null,
|
||||
tags: series.tags ?? null,
|
||||
settlement_sources: settlementSources,
|
||||
contract_url: series.contract_url ?? null,
|
||||
contract_terms_url: series.contract_terms_url ?? null,
|
||||
fee_type: series.fee_type ?? null,
|
||||
fee_multiplier: series.fee_multiplier ?? null,
|
||||
additional_prohibitions: series.additional_prohibitions ?? null,
|
||||
product_metadata: series.product_metadata ?? null,
|
||||
volume: series.volume ?? null,
|
||||
volume_fp: series.volume_fp ?? null,
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
series: {
|
||||
type: 'object',
|
||||
description: 'Series object with full details matching Kalshi API response',
|
||||
properties: {
|
||||
ticker: { type: 'string', description: 'Series ticker' },
|
||||
title: { type: 'string', description: 'Series title' },
|
||||
frequency: { type: 'string', description: 'Event frequency' },
|
||||
category: { type: 'string', description: 'Series category' },
|
||||
tags: { type: 'array', description: 'Series tags' },
|
||||
settlement_sources: { type: 'array', description: 'Settlement sources' },
|
||||
contract_url: { type: 'string', description: 'Contract URL' },
|
||||
contract_terms_url: { type: 'string', description: 'Contract terms URL' },
|
||||
fee_type: { type: 'string', description: 'Fee type' },
|
||||
fee_multiplier: { type: 'number', description: 'Fee multiplier' },
|
||||
additional_prohibitions: { type: 'array', description: 'Additional prohibitions' },
|
||||
product_metadata: { type: 'object', description: 'Product metadata' },
|
||||
volume: { type: 'number', description: 'Series volume' },
|
||||
volume_fp: { type: 'number', description: 'Volume (fixed-point)' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -80,3 +80,138 @@ export const kalshiGetTradesTool: ToolConfig<KalshiGetTradesParams, KalshiGetTra
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* V2 Get Trades Tool - Returns exact Kalshi API response structure with additional params
|
||||
*/
|
||||
export interface KalshiGetTradesV2Params extends KalshiPaginationParams {
|
||||
ticker?: string // Filter by market ticker
|
||||
minTs?: number // Minimum timestamp (Unix seconds)
|
||||
maxTs?: number // Maximum timestamp (Unix seconds)
|
||||
}
|
||||
|
||||
export interface KalshiGetTradesV2Response {
|
||||
success: boolean
|
||||
output: {
|
||||
trades: Array<{
|
||||
trade_id: string | null
|
||||
ticker: string
|
||||
yes_price: number | null
|
||||
no_price: number | null
|
||||
count: number | null
|
||||
count_fp: number | null
|
||||
created_time: string | null
|
||||
taker_side: string | null
|
||||
}>
|
||||
cursor: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export const kalshiGetTradesV2Tool: ToolConfig<KalshiGetTradesV2Params, KalshiGetTradesV2Response> =
|
||||
{
|
||||
id: 'kalshi_get_trades_v2',
|
||||
name: 'Get Trades from Kalshi V2',
|
||||
description:
|
||||
'Retrieve recent trades with additional filtering options (V2 - includes trade_id and count_fp)',
|
||||
version: '2.0.0',
|
||||
|
||||
params: {
|
||||
ticker: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by market ticker',
|
||||
},
|
||||
minTs: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Minimum timestamp (Unix seconds)',
|
||||
},
|
||||
maxTs: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Maximum timestamp (Unix seconds)',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of results (1-1000, default: 100)',
|
||||
},
|
||||
cursor: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Pagination cursor for next page',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.ticker) queryParams.append('ticker', params.ticker)
|
||||
if (params.minTs) queryParams.append('min_ts', params.minTs.toString())
|
||||
if (params.maxTs) queryParams.append('max_ts', params.maxTs.toString())
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.cursor) queryParams.append('cursor', params.cursor)
|
||||
|
||||
const query = queryParams.toString()
|
||||
const url = buildKalshiUrl('/markets/trades')
|
||||
return query ? `${url}?${query}` : url
|
||||
},
|
||||
method: 'GET',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handleKalshiError(data, response.status, 'get_trades_v2')
|
||||
}
|
||||
|
||||
const trades = (data.trades || []).map((t: Record<string, unknown>) => ({
|
||||
trade_id: t.trade_id ?? null,
|
||||
ticker: t.ticker ?? null,
|
||||
yes_price: t.yes_price ?? null,
|
||||
no_price: t.no_price ?? null,
|
||||
count: t.count ?? null,
|
||||
count_fp: t.count_fp ?? null,
|
||||
created_time: t.created_time ?? null,
|
||||
taker_side: t.taker_side ?? null,
|
||||
}))
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
trades,
|
||||
cursor: data.cursor ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
trades: {
|
||||
type: 'array',
|
||||
description: 'Array of trade objects with trade_id and count_fp',
|
||||
properties: {
|
||||
trade_id: { type: 'string', description: 'Trade ID' },
|
||||
ticker: { type: 'string', description: 'Market ticker' },
|
||||
yes_price: { type: 'number', description: 'Yes price' },
|
||||
no_price: { type: 'number', description: 'No price' },
|
||||
count: { type: 'number', description: 'Number of contracts' },
|
||||
count_fp: { type: 'number', description: 'Count (fixed-point)' },
|
||||
created_time: { type: 'string', description: 'Trade creation time' },
|
||||
taker_side: { type: 'string', description: 'Taker side (yes/no)' },
|
||||
},
|
||||
},
|
||||
cursor: {
|
||||
type: 'string',
|
||||
description: 'Pagination cursor for fetching more results',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
export { kalshiAmendOrderTool } from './amend_order'
|
||||
export { kalshiCancelOrderTool } from './cancel_order'
|
||||
export { kalshiCreateOrderTool } from './create_order'
|
||||
export { kalshiGetBalanceTool } from './get_balance'
|
||||
export { kalshiGetCandlesticksTool } from './get_candlesticks'
|
||||
export { kalshiGetEventTool } from './get_event'
|
||||
export { kalshiGetEventsTool } from './get_events'
|
||||
export { kalshiGetExchangeStatusTool } from './get_exchange_status'
|
||||
export { kalshiGetFillsTool } from './get_fills'
|
||||
export { kalshiGetMarketTool } from './get_market'
|
||||
export { kalshiGetMarketsTool } from './get_markets'
|
||||
export { kalshiGetOrderTool } from './get_order'
|
||||
export { kalshiGetOrderbookTool } from './get_orderbook'
|
||||
export { kalshiGetOrdersTool } from './get_orders'
|
||||
export { kalshiGetPositionsTool } from './get_positions'
|
||||
export { kalshiGetSeriesByTickerTool } from './get_series_by_ticker'
|
||||
export { kalshiGetTradesTool } from './get_trades'
|
||||
export { kalshiAmendOrderTool, kalshiAmendOrderV2Tool } from './amend_order'
|
||||
export { kalshiCancelOrderTool, kalshiCancelOrderV2Tool } from './cancel_order'
|
||||
export { kalshiCreateOrderTool, kalshiCreateOrderV2Tool } from './create_order'
|
||||
export { kalshiGetBalanceTool, kalshiGetBalanceV2Tool } from './get_balance'
|
||||
export { kalshiGetCandlesticksTool, kalshiGetCandlesticksV2Tool } from './get_candlesticks'
|
||||
export { kalshiGetEventTool, kalshiGetEventV2Tool } from './get_event'
|
||||
export { kalshiGetEventsTool, kalshiGetEventsV2Tool } from './get_events'
|
||||
export { kalshiGetExchangeStatusTool, kalshiGetExchangeStatusV2Tool } from './get_exchange_status'
|
||||
export { kalshiGetFillsTool, kalshiGetFillsV2Tool } from './get_fills'
|
||||
export { kalshiGetMarketTool, kalshiGetMarketV2Tool } from './get_market'
|
||||
export { kalshiGetMarketsTool, kalshiGetMarketsV2Tool } from './get_markets'
|
||||
export { kalshiGetOrderTool, kalshiGetOrderV2Tool } from './get_order'
|
||||
export { kalshiGetOrderbookTool, kalshiGetOrderbookV2Tool } from './get_orderbook'
|
||||
export { kalshiGetOrdersTool, kalshiGetOrdersV2Tool } from './get_orders'
|
||||
export { kalshiGetPositionsTool, kalshiGetPositionsV2Tool } from './get_positions'
|
||||
export { kalshiGetSeriesByTickerTool, kalshiGetSeriesByTickerV2Tool } from './get_series_by_ticker'
|
||||
export { kalshiGetTradesTool, kalshiGetTradesV2Tool } from './get_trades'
|
||||
|
||||
206
apps/sim/tools/polymarket/get_activity.ts
Normal file
206
apps/sim/tools/polymarket/get_activity.ts
Normal file
@@ -0,0 +1,206 @@
|
||||
import type { PolymarketActivity } from '@/tools/polymarket/types'
|
||||
import { buildDataUrl, handlePolymarketError } from '@/tools/polymarket/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export interface PolymarketGetActivityParams {
|
||||
user: string
|
||||
limit?: string
|
||||
offset?: string
|
||||
market?: string
|
||||
eventId?: string
|
||||
type?: string
|
||||
start?: number
|
||||
end?: number
|
||||
sortBy?: string
|
||||
sortDirection?: string
|
||||
side?: string
|
||||
}
|
||||
|
||||
export interface PolymarketGetActivityResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
activity: PolymarketActivity[]
|
||||
}
|
||||
}
|
||||
|
||||
export const polymarketGetActivityTool: ToolConfig<
|
||||
PolymarketGetActivityParams,
|
||||
PolymarketGetActivityResponse
|
||||
> = {
|
||||
id: 'polymarket_get_activity',
|
||||
name: 'Get Activity from Polymarket',
|
||||
description:
|
||||
'Retrieve on-chain activity for a user including trades, splits, merges, redemptions, rewards, and conversions',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
user: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
description: 'User wallet address (0x-prefixed)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Maximum results (default: 100, max: 500)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
offset: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Pagination offset (default: 0, max: 10000)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
market: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Comma-separated condition IDs (mutually exclusive with eventId)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
eventId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Comma-separated event IDs (mutually exclusive with market)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
type: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description:
|
||||
'Activity type filter: TRADE, SPLIT, MERGE, REDEEM, REWARD, CONVERSION, MAKER_REBATE',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
start: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
description: 'Start timestamp (Unix seconds)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
end: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
description: 'End timestamp (Unix seconds)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
sortBy: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Sort field: TIMESTAMP, TOKENS, or CASH (default: TIMESTAMP)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
sortDirection: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Sort direction: ASC or DESC (default: DESC)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
side: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Trade side filter: BUY or SELL (only applies to trades)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
queryParams.append('user', params.user)
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.offset) queryParams.append('offset', params.offset)
|
||||
if (params.market) queryParams.append('market', params.market)
|
||||
if (params.eventId) queryParams.append('eventId', params.eventId)
|
||||
if (params.type) queryParams.append('type', params.type)
|
||||
if (params.start != null && !Number.isNaN(params.start))
|
||||
queryParams.append('start', String(params.start))
|
||||
if (params.end != null && !Number.isNaN(params.end))
|
||||
queryParams.append('end', String(params.end))
|
||||
if (params.sortBy) queryParams.append('sortBy', params.sortBy)
|
||||
if (params.sortDirection) queryParams.append('sortDirection', params.sortDirection)
|
||||
if (params.side) queryParams.append('side', params.side)
|
||||
return `${buildDataUrl('/activity')}?${queryParams.toString()}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handlePolymarketError(data, response.status, 'get_activity')
|
||||
}
|
||||
|
||||
const activityList = Array.isArray(data) ? data : []
|
||||
|
||||
const activity: PolymarketActivity[] = activityList.map((a: any) => ({
|
||||
proxyWallet: a.proxyWallet ?? null,
|
||||
timestamp: a.timestamp ?? 0,
|
||||
conditionId: a.conditionId ?? '',
|
||||
type: a.type ?? '',
|
||||
size: a.size ?? 0,
|
||||
usdcSize: a.usdcSize ?? 0,
|
||||
transactionHash: a.transactionHash ?? null,
|
||||
price: a.price ?? null,
|
||||
asset: a.asset ?? null,
|
||||
side: a.side ?? null,
|
||||
outcomeIndex: a.outcomeIndex ?? null,
|
||||
title: a.title ?? null,
|
||||
slug: a.slug ?? null,
|
||||
icon: a.icon ?? null,
|
||||
eventSlug: a.eventSlug ?? null,
|
||||
outcome: a.outcome ?? null,
|
||||
name: a.name ?? null,
|
||||
pseudonym: a.pseudonym ?? null,
|
||||
bio: a.bio ?? null,
|
||||
profileImage: a.profileImage ?? null,
|
||||
profileImageOptimized: a.profileImageOptimized ?? null,
|
||||
}))
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
activity,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
activity: {
|
||||
type: 'array',
|
||||
description: 'Array of activity entries',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
proxyWallet: { type: 'string', description: 'User proxy wallet address' },
|
||||
timestamp: { type: 'number', description: 'Unix timestamp of activity' },
|
||||
conditionId: { type: 'string', description: 'Market condition ID' },
|
||||
type: {
|
||||
type: 'string',
|
||||
description: 'Activity type (TRADE, SPLIT, MERGE, REDEEM, REWARD, CONVERSION)',
|
||||
},
|
||||
size: { type: 'number', description: 'Size in tokens' },
|
||||
usdcSize: { type: 'number', description: 'Size in USDC' },
|
||||
transactionHash: { type: 'string', description: 'Blockchain transaction hash' },
|
||||
price: { type: 'number', description: 'Price (for trades)' },
|
||||
asset: { type: 'string', description: 'Asset/token ID' },
|
||||
side: { type: 'string', description: 'Trade side (BUY/SELL)' },
|
||||
outcomeIndex: { type: 'number', description: 'Outcome index' },
|
||||
title: { type: 'string', description: 'Market title' },
|
||||
slug: { type: 'string', description: 'Market slug' },
|
||||
icon: { type: 'string', description: 'Market icon URL' },
|
||||
eventSlug: { type: 'string', description: 'Event slug' },
|
||||
outcome: { type: 'string', description: 'Outcome name' },
|
||||
name: { type: 'string', description: 'User display name' },
|
||||
pseudonym: { type: 'string', description: 'User pseudonym' },
|
||||
bio: { type: 'string', description: 'User bio' },
|
||||
profileImage: { type: 'string', description: 'User profile image URL' },
|
||||
profileImageOptimized: { type: 'string', description: 'Optimized profile image URL' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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
|
||||
@@ -71,6 +71,26 @@ export const polymarketGetEventTool: ToolConfig<
|
||||
event: {
|
||||
type: 'object',
|
||||
description: 'Event object with details',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Event ID' },
|
||||
ticker: { type: 'string', description: 'Event ticker' },
|
||||
slug: { type: 'string', description: 'Event slug' },
|
||||
title: { type: 'string', description: 'Event title' },
|
||||
description: { type: 'string', description: 'Event description' },
|
||||
startDate: { type: 'string', description: 'Start date' },
|
||||
creationDate: { type: 'string', description: 'Creation date' },
|
||||
endDate: { type: 'string', description: 'End date' },
|
||||
image: { type: 'string', description: 'Event image URL' },
|
||||
icon: { type: 'string', description: 'Event icon URL' },
|
||||
active: { type: 'boolean', description: 'Whether event is active' },
|
||||
closed: { type: 'boolean', description: 'Whether event is closed' },
|
||||
archived: { type: 'boolean', description: 'Whether event is archived' },
|
||||
liquidity: { type: 'number', description: 'Total liquidity' },
|
||||
volume: { type: 'number', description: 'Total volume' },
|
||||
openInterest: { type: 'number', description: 'Open interest' },
|
||||
commentCount: { type: 'number', description: 'Comment count' },
|
||||
markets: { type: 'array', description: 'Array of markets in this event' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
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 // 'true' or 'false' - filter for closed/active events
|
||||
order?: string // sort field (e.g., 'volume', 'liquidity', 'startDate', 'endDate')
|
||||
ascending?: string // 'true' or 'false' - sort direction
|
||||
tagId?: string // filter by tag ID
|
||||
closed?: string
|
||||
order?: string
|
||||
ascending?: string
|
||||
tagId?: string
|
||||
}
|
||||
|
||||
export interface PolymarketGetEventsResponse {
|
||||
@@ -29,7 +29,7 @@ export const polymarketGetEventsTool: ToolConfig<
|
||||
closed: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Filter by closed status (true/false). Use false for active events only.',
|
||||
description: 'Filter by closed status (true/false). Use false for open events only.',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
order: {
|
||||
@@ -71,13 +71,11 @@ export const polymarketGetEventsTool: ToolConfig<
|
||||
if (params.order) queryParams.append('order', params.order)
|
||||
if (params.ascending) queryParams.append('ascending', params.ascending)
|
||||
if (params.tagId) queryParams.append('tag_id', params.tagId)
|
||||
// Default limit to 50 to prevent browser crashes from large data sets
|
||||
queryParams.append('limit', params.limit || '50')
|
||||
if (params.offset) queryParams.append('offset', params.offset)
|
||||
|
||||
const query = queryParams.toString()
|
||||
const url = buildGammaUrl('/events')
|
||||
return `${url}?${query}`
|
||||
return `${url}?${queryParams.toString()}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: () => ({
|
||||
@@ -92,7 +90,6 @@ export const polymarketGetEventsTool: ToolConfig<
|
||||
handlePolymarketError(data, response.status, 'get_events')
|
||||
}
|
||||
|
||||
// Response is an array of events
|
||||
const events = Array.isArray(data) ? data : []
|
||||
|
||||
return {
|
||||
@@ -107,6 +104,26 @@ export const polymarketGetEventsTool: ToolConfig<
|
||||
events: {
|
||||
type: 'array',
|
||||
description: 'Array of event objects',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Event ID' },
|
||||
ticker: { type: 'string', description: 'Event ticker' },
|
||||
slug: { type: 'string', description: 'Event slug' },
|
||||
title: { type: 'string', description: 'Event title' },
|
||||
description: { type: 'string', description: 'Event description' },
|
||||
startDate: { type: 'string', description: 'Start date' },
|
||||
endDate: { type: 'string', description: 'End date' },
|
||||
image: { type: 'string', description: 'Event image URL' },
|
||||
icon: { type: 'string', description: 'Event icon URL' },
|
||||
active: { type: 'boolean', description: 'Whether event is active' },
|
||||
closed: { type: 'boolean', description: 'Whether event is closed' },
|
||||
archived: { type: 'boolean', description: 'Whether event is archived' },
|
||||
liquidity: { type: 'number', description: 'Total liquidity' },
|
||||
volume: { type: 'number', description: 'Total volume' },
|
||||
markets: { type: 'array', description: 'Array of markets in this event' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
132
apps/sim/tools/polymarket/get_holders.ts
Normal file
132
apps/sim/tools/polymarket/get_holders.ts
Normal file
@@ -0,0 +1,132 @@
|
||||
import type { PolymarketMarketHolders } from '@/tools/polymarket/types'
|
||||
import { buildDataUrl, handlePolymarketError } from '@/tools/polymarket/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export interface PolymarketGetHoldersParams {
|
||||
market: string
|
||||
limit?: string
|
||||
minBalance?: string
|
||||
}
|
||||
|
||||
export interface PolymarketGetHoldersResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
holders: PolymarketMarketHolders[]
|
||||
}
|
||||
}
|
||||
|
||||
export const polymarketGetHoldersTool: ToolConfig<
|
||||
PolymarketGetHoldersParams,
|
||||
PolymarketGetHoldersResponse
|
||||
> = {
|
||||
id: 'polymarket_get_holders',
|
||||
name: 'Get Market Holders from Polymarket',
|
||||
description: 'Retrieve top holders of a specific market token',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
market: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
description: 'Comma-separated list of condition IDs',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Number of holders to return (0-20, default: 20)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
minBalance: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Minimum balance threshold (default: 1)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
queryParams.append('market', params.market)
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.minBalance) queryParams.append('minBalance', params.minBalance)
|
||||
return `${buildDataUrl('/holders')}?${queryParams.toString()}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handlePolymarketError(data, response.status, 'get_holders')
|
||||
}
|
||||
|
||||
const marketHolders = Array.isArray(data) ? data : []
|
||||
|
||||
const holders: PolymarketMarketHolders[] = marketHolders.map((mh: any) => ({
|
||||
token: mh.token ?? '',
|
||||
holders: (mh.holders ?? []).map((h: any) => ({
|
||||
proxyWallet: h.proxyWallet ?? '',
|
||||
bio: h.bio ?? null,
|
||||
asset: h.asset ?? '',
|
||||
pseudonym: h.pseudonym ?? null,
|
||||
amount: h.amount ?? 0,
|
||||
displayUsernamePublic: h.displayUsernamePublic ?? false,
|
||||
outcomeIndex: h.outcomeIndex ?? 0,
|
||||
name: h.name ?? null,
|
||||
profileImage: h.profileImage ?? null,
|
||||
profileImageOptimized: h.profileImageOptimized ?? null,
|
||||
})),
|
||||
}))
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
holders,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
holders: {
|
||||
type: 'array',
|
||||
description: 'Array of market holder groups by token',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
token: { type: 'string', description: 'Token/asset ID' },
|
||||
holders: {
|
||||
type: 'array',
|
||||
description: 'Array of holders for this token',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
proxyWallet: { type: 'string', description: 'Holder wallet address' },
|
||||
bio: { type: 'string', description: 'Holder bio' },
|
||||
asset: { type: 'string', description: 'Asset ID' },
|
||||
pseudonym: { type: 'string', description: 'Holder pseudonym' },
|
||||
amount: { type: 'number', description: 'Amount held' },
|
||||
displayUsernamePublic: {
|
||||
type: 'boolean',
|
||||
description: 'Whether username is publicly displayed',
|
||||
},
|
||||
outcomeIndex: { type: 'number', description: 'Outcome index' },
|
||||
name: { type: 'string', description: 'Holder display name' },
|
||||
profileImage: { type: 'string', description: 'Profile image URL' },
|
||||
profileImageOptimized: {
|
||||
type: 'string',
|
||||
description: 'Optimized profile image URL',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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)
|
||||
@@ -9,6 +9,7 @@ export interface PolymarketGetLastTradePriceResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
price: string
|
||||
side: string
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +53,8 @@ export const polymarketGetLastTradePriceTool: ToolConfig<
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
price: typeof data === 'string' ? data : data.price || '',
|
||||
price: data.price ?? '',
|
||||
side: data.side ?? '',
|
||||
},
|
||||
}
|
||||
},
|
||||
@@ -62,5 +64,9 @@ export const polymarketGetLastTradePriceTool: ToolConfig<
|
||||
type: 'string',
|
||||
description: 'Last trade price',
|
||||
},
|
||||
side: {
|
||||
type: 'string',
|
||||
description: 'Side of the last trade (BUY or SELL)',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
143
apps/sim/tools/polymarket/get_leaderboard.ts
Normal file
143
apps/sim/tools/polymarket/get_leaderboard.ts
Normal file
@@ -0,0 +1,143 @@
|
||||
import type { PolymarketLeaderboardEntry } from '@/tools/polymarket/types'
|
||||
import { buildDataUrl, handlePolymarketError } from '@/tools/polymarket/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export interface PolymarketGetLeaderboardParams {
|
||||
category?: string
|
||||
timePeriod?: string
|
||||
orderBy?: string
|
||||
limit?: string
|
||||
offset?: string
|
||||
user?: string
|
||||
userName?: string
|
||||
}
|
||||
|
||||
export interface PolymarketGetLeaderboardResponse {
|
||||
success: boolean
|
||||
output: {
|
||||
leaderboard: PolymarketLeaderboardEntry[]
|
||||
}
|
||||
}
|
||||
|
||||
export const polymarketGetLeaderboardTool: ToolConfig<
|
||||
PolymarketGetLeaderboardParams,
|
||||
PolymarketGetLeaderboardResponse
|
||||
> = {
|
||||
id: 'polymarket_get_leaderboard',
|
||||
name: 'Get Leaderboard from Polymarket',
|
||||
description: 'Retrieve trader leaderboard rankings by profit/loss or volume',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
category: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description:
|
||||
'Category filter: OVERALL, POLITICS, SPORTS, CRYPTO, CULTURE, MENTIONS, WEATHER, ECONOMICS, TECH, FINANCE (default: OVERALL)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
timePeriod: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Time period: DAY, WEEK, MONTH, ALL (default: DAY)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
orderBy: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Order by: PNL or VOL (default: PNL)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Number of results (1-50, default: 25)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
offset: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Pagination offset (0-1000, default: 0)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
user: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Filter by specific user wallet address',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
userName: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Filter by username',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.category) queryParams.append('category', params.category)
|
||||
if (params.timePeriod) queryParams.append('timePeriod', params.timePeriod)
|
||||
if (params.orderBy) queryParams.append('orderBy', params.orderBy)
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.offset) queryParams.append('offset', params.offset)
|
||||
if (params.user) queryParams.append('user', params.user)
|
||||
if (params.userName) queryParams.append('userName', params.userName)
|
||||
const query = queryParams.toString()
|
||||
return query ? `${buildDataUrl('/v1/leaderboard')}?${query}` : buildDataUrl('/v1/leaderboard')
|
||||
},
|
||||
method: 'GET',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok) {
|
||||
handlePolymarketError(data, response.status, 'get_leaderboard')
|
||||
}
|
||||
|
||||
const entries = Array.isArray(data) ? data : []
|
||||
|
||||
const leaderboard: PolymarketLeaderboardEntry[] = entries.map((entry: any) => ({
|
||||
rank: entry.rank ?? '',
|
||||
proxyWallet: entry.proxyWallet ?? '',
|
||||
userName: entry.userName ?? null,
|
||||
vol: entry.vol ?? 0,
|
||||
pnl: entry.pnl ?? 0,
|
||||
profileImage: entry.profileImage ?? null,
|
||||
xUsername: entry.xUsername ?? null,
|
||||
verifiedBadge: entry.verifiedBadge ?? false,
|
||||
}))
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
leaderboard,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
leaderboard: {
|
||||
type: 'array',
|
||||
description: 'Array of leaderboard entries',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
rank: { type: 'string', description: 'Leaderboard rank position' },
|
||||
proxyWallet: { type: 'string', description: 'User proxy wallet address' },
|
||||
userName: { type: 'string', description: 'User display name' },
|
||||
vol: { type: 'number', description: 'Trading volume' },
|
||||
pnl: { type: 'number', description: 'Profit and loss' },
|
||||
profileImage: { type: 'string', description: 'User profile image URL' },
|
||||
xUsername: { type: 'string', description: 'Twitter/X username' },
|
||||
verifiedBadge: { type: 'boolean', description: 'Whether user has verified badge' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -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
|
||||
@@ -71,6 +71,30 @@ export const polymarketGetMarketTool: ToolConfig<
|
||||
market: {
|
||||
type: 'object',
|
||||
description: 'Market object with details',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Market ID' },
|
||||
question: { type: 'string', description: 'Market question' },
|
||||
conditionId: { type: 'string', description: 'Condition ID' },
|
||||
slug: { type: 'string', description: 'Market slug' },
|
||||
resolutionSource: { type: 'string', description: 'Resolution source' },
|
||||
endDate: { type: 'string', description: 'End date' },
|
||||
startDate: { type: 'string', description: 'Start date' },
|
||||
image: { type: 'string', description: 'Market image URL' },
|
||||
icon: { type: 'string', description: 'Market icon URL' },
|
||||
description: { type: 'string', description: 'Market description' },
|
||||
outcomes: { type: 'string', description: 'Outcomes JSON string' },
|
||||
outcomePrices: { type: 'string', description: 'Outcome prices JSON string' },
|
||||
volume: { type: 'string', description: 'Total volume' },
|
||||
liquidity: { type: 'string', description: 'Total liquidity' },
|
||||
active: { type: 'boolean', description: 'Whether market is active' },
|
||||
closed: { type: 'boolean', description: 'Whether market is closed' },
|
||||
archived: { type: 'boolean', description: 'Whether market is archived' },
|
||||
volumeNum: { type: 'number', description: 'Volume as number' },
|
||||
liquidityNum: { type: 'number', description: 'Liquidity as number' },
|
||||
clobTokenIds: { type: 'array', description: 'CLOB token IDs' },
|
||||
acceptingOrders: { type: 'boolean', description: 'Whether accepting orders' },
|
||||
negRisk: { type: 'boolean', description: 'Whether negative risk' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
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 // 'true' or 'false' - filter for closed/active markets
|
||||
order?: string // sort field - use camelCase (e.g., 'volumeNum', 'liquidityNum', 'startDate', 'endDate')
|
||||
ascending?: string // 'true' or 'false' - sort direction
|
||||
tagId?: string // filter by tag ID
|
||||
closed?: string
|
||||
order?: string
|
||||
ascending?: string
|
||||
tagId?: string
|
||||
}
|
||||
|
||||
export interface PolymarketGetMarketsResponse {
|
||||
@@ -29,7 +29,7 @@ export const polymarketGetMarketsTool: ToolConfig<
|
||||
closed: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Filter by closed status (true/false). Use false for active markets only.',
|
||||
description: 'Filter by closed status (true/false). Use false for open markets only.',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
order: {
|
||||
@@ -71,13 +71,11 @@ export const polymarketGetMarketsTool: ToolConfig<
|
||||
if (params.order) queryParams.append('order', params.order)
|
||||
if (params.ascending) queryParams.append('ascending', params.ascending)
|
||||
if (params.tagId) queryParams.append('tag_id', params.tagId)
|
||||
// Default limit to 50 to prevent browser crashes from large data sets
|
||||
queryParams.append('limit', params.limit || '50')
|
||||
if (params.offset) queryParams.append('offset', params.offset)
|
||||
|
||||
const query = queryParams.toString()
|
||||
const url = buildGammaUrl('/markets')
|
||||
return `${url}?${query}`
|
||||
return `${url}?${queryParams.toString()}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: () => ({
|
||||
@@ -107,6 +105,26 @@ export const polymarketGetMarketsTool: ToolConfig<
|
||||
markets: {
|
||||
type: 'array',
|
||||
description: 'Array of market objects',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Market ID' },
|
||||
question: { type: 'string', description: 'Market question' },
|
||||
conditionId: { type: 'string', description: 'Condition ID' },
|
||||
slug: { type: 'string', description: 'Market slug' },
|
||||
endDate: { type: 'string', description: 'End date' },
|
||||
image: { type: 'string', description: 'Market image URL' },
|
||||
outcomes: { type: 'string', description: 'Outcomes JSON string' },
|
||||
outcomePrices: { type: 'string', description: 'Outcome prices JSON string' },
|
||||
volume: { type: 'string', description: 'Total volume' },
|
||||
liquidity: { type: 'string', description: 'Total liquidity' },
|
||||
active: { type: 'boolean', description: 'Whether market is active' },
|
||||
closed: { type: 'boolean', description: 'Whether market is closed' },
|
||||
volumeNum: { type: 'number', description: 'Volume as number' },
|
||||
liquidityNum: { type: 'number', description: 'Liquidity as number' },
|
||||
clobTokenIds: { type: 'array', description: 'CLOB token IDs' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
@@ -50,10 +50,22 @@ export const polymarketGetOrderbookTool: ToolConfig<
|
||||
handlePolymarketError(data, response.status, 'get_orderbook')
|
||||
}
|
||||
|
||||
const orderbook: PolymarketOrderBook = {
|
||||
market: data.market ?? '',
|
||||
asset_id: data.asset_id ?? '',
|
||||
hash: data.hash ?? '',
|
||||
timestamp: data.timestamp ?? '',
|
||||
bids: data.bids ?? [],
|
||||
asks: data.asks ?? [],
|
||||
min_order_size: data.min_order_size ?? '0',
|
||||
tick_size: data.tick_size ?? '0',
|
||||
neg_risk: data.neg_risk ?? false,
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
orderbook: data,
|
||||
orderbook,
|
||||
},
|
||||
}
|
||||
},
|
||||
@@ -62,6 +74,37 @@ export const polymarketGetOrderbookTool: ToolConfig<
|
||||
orderbook: {
|
||||
type: 'object',
|
||||
description: 'Order book with bids and asks arrays',
|
||||
properties: {
|
||||
market: { type: 'string', description: 'Market identifier' },
|
||||
asset_id: { type: 'string', description: 'Asset token ID' },
|
||||
hash: { type: 'string', description: 'Order book hash' },
|
||||
timestamp: { type: 'string', description: 'Timestamp' },
|
||||
bids: {
|
||||
type: 'array',
|
||||
description: 'Bid orders',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
price: { type: 'string', description: 'Bid price' },
|
||||
size: { type: 'string', description: 'Bid size' },
|
||||
},
|
||||
},
|
||||
},
|
||||
asks: {
|
||||
type: 'array',
|
||||
description: 'Ask orders',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
price: { type: 'string', description: 'Ask price' },
|
||||
size: { type: 'string', description: 'Ask size' },
|
||||
},
|
||||
},
|
||||
},
|
||||
min_order_size: { type: 'string', description: 'Minimum order size' },
|
||||
tick_size: { type: 'string', description: 'Tick size' },
|
||||
neg_risk: { type: 'boolean', description: 'Whether negative risk' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
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 // Wallet address (required)
|
||||
market?: string // Optional market filter
|
||||
user: string
|
||||
market?: string
|
||||
eventId?: string
|
||||
sizeThreshold?: string
|
||||
redeemable?: string
|
||||
mergeable?: string
|
||||
sortBy?: string
|
||||
sortDirection?: string
|
||||
title?: string
|
||||
limit?: string
|
||||
offset?: string
|
||||
}
|
||||
|
||||
export interface PolymarketGetPositionsResponse {
|
||||
@@ -33,7 +42,63 @@ export const polymarketGetPositionsTool: ToolConfig<
|
||||
market: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Optional market ID to filter positions',
|
||||
description:
|
||||
'Condition IDs to filter positions (comma-separated, mutually exclusive with eventId)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
eventId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Event ID to filter positions (mutually exclusive with market)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
sizeThreshold: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Minimum position size threshold (default: 1)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
redeemable: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Filter for redeemable positions only (true/false)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
mergeable: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Filter for mergeable positions only (true/false)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
sortBy: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description:
|
||||
'Sort field (TOKENS, CURRENT, INITIAL, CASHPNL, PERCENTPNL, TITLE, RESOLVING, PRICE, AVGPRICE)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
sortDirection: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Sort direction (ASC or DESC)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
title: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Search filter by title',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Number of results per page',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
offset: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Pagination offset',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
},
|
||||
@@ -43,6 +108,15 @@ export const polymarketGetPositionsTool: ToolConfig<
|
||||
const queryParams = new URLSearchParams()
|
||||
queryParams.append('user', params.user)
|
||||
if (params.market) queryParams.append('market', params.market)
|
||||
if (params.eventId) queryParams.append('eventId', params.eventId)
|
||||
if (params.sizeThreshold) queryParams.append('sizeThreshold', params.sizeThreshold)
|
||||
if (params.redeemable) queryParams.append('redeemable', params.redeemable)
|
||||
if (params.mergeable) queryParams.append('mergeable', params.mergeable)
|
||||
if (params.sortBy) queryParams.append('sortBy', params.sortBy)
|
||||
if (params.sortDirection) queryParams.append('sortDirection', params.sortDirection)
|
||||
if (params.title) queryParams.append('title', params.title)
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.offset) queryParams.append('offset', params.offset)
|
||||
|
||||
return `${buildDataUrl('/positions')}?${queryParams.toString()}`
|
||||
},
|
||||
@@ -59,8 +133,34 @@ export const polymarketGetPositionsTool: ToolConfig<
|
||||
handlePolymarketError(data, response.status, 'get_positions')
|
||||
}
|
||||
|
||||
// Response is an array of positions
|
||||
const positions = Array.isArray(data) ? data : []
|
||||
const rawPositions = Array.isArray(data) ? data : []
|
||||
const positions: PolymarketPosition[] = rawPositions.map((p: Record<string, unknown>) => ({
|
||||
proxyWallet: (p.proxyWallet as string) ?? null,
|
||||
asset: (p.asset as string) ?? '',
|
||||
conditionId: (p.conditionId as string) ?? '',
|
||||
size: (p.size as number) ?? 0,
|
||||
avgPrice: (p.avgPrice as number) ?? 0,
|
||||
initialValue: (p.initialValue as number) ?? 0,
|
||||
currentValue: (p.currentValue as number) ?? 0,
|
||||
cashPnl: (p.cashPnl as number) ?? 0,
|
||||
percentPnl: (p.percentPnl as number) ?? 0,
|
||||
totalBought: (p.totalBought as number) ?? 0,
|
||||
realizedPnl: (p.realizedPnl as number) ?? 0,
|
||||
percentRealizedPnl: (p.percentRealizedPnl as number) ?? 0,
|
||||
curPrice: (p.curPrice as number) ?? 0,
|
||||
redeemable: (p.redeemable as boolean) ?? false,
|
||||
mergeable: (p.mergeable as boolean) ?? false,
|
||||
title: (p.title as string) ?? null,
|
||||
slug: (p.slug as string) ?? null,
|
||||
icon: (p.icon as string) ?? null,
|
||||
eventSlug: (p.eventSlug as string) ?? null,
|
||||
outcome: (p.outcome as string) ?? null,
|
||||
outcomeIndex: (p.outcomeIndex as number) ?? null,
|
||||
oppositeOutcome: (p.oppositeOutcome as string) ?? null,
|
||||
oppositeAsset: (p.oppositeAsset as string) ?? null,
|
||||
endDate: (p.endDate as string) ?? null,
|
||||
negativeRisk: (p.negativeRisk as boolean) ?? false,
|
||||
}))
|
||||
|
||||
return {
|
||||
success: true,
|
||||
@@ -74,6 +174,36 @@ export const polymarketGetPositionsTool: ToolConfig<
|
||||
positions: {
|
||||
type: 'array',
|
||||
description: 'Array of position objects',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
proxyWallet: { type: 'string', description: 'Proxy wallet address' },
|
||||
asset: { type: 'string', description: 'Asset token ID' },
|
||||
conditionId: { type: 'string', description: 'Condition ID' },
|
||||
size: { type: 'number', description: 'Position size' },
|
||||
avgPrice: { type: 'number', description: 'Average price' },
|
||||
initialValue: { type: 'number', description: 'Initial value' },
|
||||
currentValue: { type: 'number', description: 'Current value' },
|
||||
cashPnl: { type: 'number', description: 'Cash profit/loss' },
|
||||
percentPnl: { type: 'number', description: 'Percent profit/loss' },
|
||||
totalBought: { type: 'number', description: 'Total bought' },
|
||||
realizedPnl: { type: 'number', description: 'Realized profit/loss' },
|
||||
percentRealizedPnl: { type: 'number', description: 'Percent realized profit/loss' },
|
||||
curPrice: { type: 'number', description: 'Current price' },
|
||||
redeemable: { type: 'boolean', description: 'Whether position is redeemable' },
|
||||
mergeable: { type: 'boolean', description: 'Whether position is mergeable' },
|
||||
title: { type: 'string', description: 'Market title' },
|
||||
slug: { type: 'string', description: 'Market slug' },
|
||||
icon: { type: 'string', description: 'Market icon URL' },
|
||||
eventSlug: { type: 'string', description: 'Event slug' },
|
||||
outcome: { type: 'string', description: 'Outcome name' },
|
||||
outcomeIndex: { type: 'number', description: 'Outcome index' },
|
||||
oppositeOutcome: { type: 'string', description: 'Opposite outcome name' },
|
||||
oppositeAsset: { type: 'string', description: 'Opposite asset token ID' },
|
||||
endDate: { type: 'string', description: 'End date' },
|
||||
negativeRisk: { type: 'boolean', description: 'Whether negative risk' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -99,7 +99,14 @@ export const polymarketGetPriceHistoryTool: ToolConfig<
|
||||
outputs: {
|
||||
history: {
|
||||
type: 'array',
|
||||
description: 'Array of price history entries with timestamp (t) and price (p)',
|
||||
description: 'Array of price history entries',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
t: { type: 'number', description: 'Unix timestamp' },
|
||||
p: { type: 'number', description: 'Price at timestamp' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
@@ -97,6 +97,26 @@ export const polymarketGetSeriesTool: ToolConfig<
|
||||
series: {
|
||||
type: 'array',
|
||||
description: 'Array of series objects',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Series ID' },
|
||||
ticker: { type: 'string', description: 'Series ticker' },
|
||||
slug: { type: 'string', description: 'Series slug' },
|
||||
title: { type: 'string', description: 'Series title' },
|
||||
seriesType: { type: 'string', description: 'Series type' },
|
||||
recurrence: { type: 'string', description: 'Recurrence pattern' },
|
||||
image: { type: 'string', description: 'Series image URL' },
|
||||
icon: { type: 'string', description: 'Series icon URL' },
|
||||
active: { type: 'boolean', description: 'Whether series is active' },
|
||||
closed: { type: 'boolean', description: 'Whether series is closed' },
|
||||
archived: { type: 'boolean', description: 'Whether series is archived' },
|
||||
featured: { type: 'boolean', description: 'Whether series is featured' },
|
||||
volume: { type: 'number', description: 'Total volume' },
|
||||
liquidity: { type: 'number', description: 'Total liquidity' },
|
||||
eventCount: { type: 'number', description: 'Number of events in series' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -58,6 +58,25 @@ export const polymarketGetSeriesByIdTool: ToolConfig<
|
||||
series: {
|
||||
type: 'object',
|
||||
description: 'Series object with details',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Series ID' },
|
||||
ticker: { type: 'string', description: 'Series ticker' },
|
||||
slug: { type: 'string', description: 'Series slug' },
|
||||
title: { type: 'string', description: 'Series title' },
|
||||
seriesType: { type: 'string', description: 'Series type' },
|
||||
recurrence: { type: 'string', description: 'Recurrence pattern' },
|
||||
image: { type: 'string', description: 'Series image URL' },
|
||||
icon: { type: 'string', description: 'Series icon URL' },
|
||||
active: { type: 'boolean', description: 'Whether series is active' },
|
||||
closed: { type: 'boolean', description: 'Whether series is closed' },
|
||||
archived: { type: 'boolean', description: 'Whether series is archived' },
|
||||
featured: { type: 'boolean', description: 'Whether series is featured' },
|
||||
volume: { type: 'number', description: 'Total volume' },
|
||||
liquidity: { type: 'number', description: 'Total liquidity' },
|
||||
commentCount: { type: 'number', description: 'Comment count' },
|
||||
eventCount: { type: 'number', description: 'Number of events in series' },
|
||||
events: { type: 'array', description: 'Array of events in this series' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
@@ -53,7 +53,9 @@ export const polymarketGetSpreadTool: ToolConfig<
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
spread: data,
|
||||
spread: {
|
||||
spread: data.spread ?? '',
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
@@ -61,7 +63,10 @@ export const polymarketGetSpreadTool: ToolConfig<
|
||||
outputs: {
|
||||
spread: {
|
||||
type: 'object',
|
||||
description: 'Bid-ask spread with bid and ask prices',
|
||||
description: 'Spread value between bid and ask',
|
||||
properties: {
|
||||
spread: { type: 'string', description: 'The spread value' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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 {}
|
||||
|
||||
@@ -71,7 +71,17 @@ export const polymarketGetTagsTool: ToolConfig<PolymarketGetTagsParams, Polymark
|
||||
outputs: {
|
||||
tags: {
|
||||
type: 'array',
|
||||
description: 'Array of tag objects with id, label, and slug',
|
||||
description: 'Array of tag objects',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'string', description: 'Tag ID' },
|
||||
label: { type: 'string', description: 'Tag label' },
|
||||
slug: { type: 'string', description: 'Tag slug' },
|
||||
createdAt: { type: 'string', description: 'Creation timestamp' },
|
||||
updatedAt: { type: 'string', description: 'Last update timestamp' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
import type { PolymarketTrade } from '@/tools/polymarket/types'
|
||||
import { buildDataUrl, handlePolymarketError } from '@/tools/polymarket/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { PolymarketPaginationParams, PolymarketTrade } from './types'
|
||||
import { buildDataUrl, handlePolymarketError } from './types'
|
||||
|
||||
export interface PolymarketGetTradesParams extends PolymarketPaginationParams {
|
||||
user?: string // Optional user wallet address
|
||||
market?: string // Optional market filter
|
||||
export interface PolymarketGetTradesParams {
|
||||
user?: string
|
||||
market?: string
|
||||
eventId?: string
|
||||
side?: string
|
||||
takerOnly?: string
|
||||
filterType?: string
|
||||
filterAmount?: string
|
||||
limit?: string
|
||||
offset?: string
|
||||
}
|
||||
|
||||
export interface PolymarketGetTradesResponse {
|
||||
@@ -33,13 +40,43 @@ export const polymarketGetTradesTool: ToolConfig<
|
||||
market: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Market ID to filter trades',
|
||||
description: 'Market/condition ID to filter trades (mutually exclusive with eventId)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
eventId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Event ID to filter trades (mutually exclusive with market)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
side: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Trade direction filter (BUY or SELL)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
takerOnly: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Filter for taker trades only (true/false, default: true)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
filterType: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Filter type (CASH or TOKENS) - requires filterAmount',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
filterAmount: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Filter amount threshold - requires filterType',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
limit: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Number of results per page (max 50)',
|
||||
description: 'Number of results per page (default: 100, max: 10000)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
offset: {
|
||||
@@ -55,13 +92,16 @@ export const polymarketGetTradesTool: ToolConfig<
|
||||
const queryParams = new URLSearchParams()
|
||||
if (params.user) queryParams.append('user', params.user)
|
||||
if (params.market) queryParams.append('market', params.market)
|
||||
// Default limit to 50 to prevent browser crashes from large data sets
|
||||
queryParams.append('limit', params.limit || '50')
|
||||
if (params.eventId) queryParams.append('eventId', params.eventId)
|
||||
if (params.side) queryParams.append('side', params.side.toUpperCase())
|
||||
if (params.takerOnly) queryParams.append('takerOnly', params.takerOnly)
|
||||
if (params.filterType) queryParams.append('filterType', params.filterType.toUpperCase())
|
||||
if (params.filterAmount) queryParams.append('filterAmount', params.filterAmount)
|
||||
if (params.limit) queryParams.append('limit', params.limit)
|
||||
if (params.offset) queryParams.append('offset', params.offset)
|
||||
|
||||
const query = queryParams.toString()
|
||||
const url = buildDataUrl('/trades')
|
||||
return `${url}?${query}`
|
||||
return `${url}?${queryParams.toString()}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: () => ({
|
||||
@@ -76,8 +116,28 @@ export const polymarketGetTradesTool: ToolConfig<
|
||||
handlePolymarketError(data, response.status, 'get_trades')
|
||||
}
|
||||
|
||||
// Response is an array of trades
|
||||
const trades = Array.isArray(data) ? data : []
|
||||
const rawTrades = Array.isArray(data) ? data : []
|
||||
const trades: PolymarketTrade[] = rawTrades.map((t: Record<string, unknown>) => ({
|
||||
proxyWallet: (t.proxyWallet as string) ?? null,
|
||||
side: (t.side as string) ?? '',
|
||||
asset: (t.asset as string) ?? '',
|
||||
conditionId: (t.conditionId as string) ?? '',
|
||||
size: (t.size as number) ?? 0,
|
||||
price: (t.price as number) ?? 0,
|
||||
timestamp: (t.timestamp as number) ?? 0,
|
||||
title: (t.title as string) ?? null,
|
||||
slug: (t.slug as string) ?? null,
|
||||
icon: (t.icon as string) ?? null,
|
||||
eventSlug: (t.eventSlug as string) ?? null,
|
||||
outcome: (t.outcome as string) ?? null,
|
||||
outcomeIndex: (t.outcomeIndex as number) ?? null,
|
||||
name: (t.name as string) ?? null,
|
||||
pseudonym: (t.pseudonym as string) ?? null,
|
||||
bio: (t.bio as string) ?? null,
|
||||
profileImage: (t.profileImage as string) ?? null,
|
||||
profileImageOptimized: (t.profileImageOptimized as string) ?? null,
|
||||
transactionHash: (t.transactionHash as string) ?? null,
|
||||
}))
|
||||
|
||||
return {
|
||||
success: true,
|
||||
@@ -91,6 +151,30 @@ export const polymarketGetTradesTool: ToolConfig<
|
||||
trades: {
|
||||
type: 'array',
|
||||
description: 'Array of trade objects',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
proxyWallet: { type: 'string', description: 'Proxy wallet address' },
|
||||
side: { type: 'string', description: 'Trade side (BUY or SELL)' },
|
||||
asset: { type: 'string', description: 'Asset token ID' },
|
||||
conditionId: { type: 'string', description: 'Condition ID' },
|
||||
size: { type: 'number', description: 'Trade size' },
|
||||
price: { type: 'number', description: 'Trade price' },
|
||||
timestamp: { type: 'number', description: 'Unix timestamp' },
|
||||
title: { type: 'string', description: 'Market title' },
|
||||
slug: { type: 'string', description: 'Market slug' },
|
||||
icon: { type: 'string', description: 'Market icon URL' },
|
||||
eventSlug: { type: 'string', description: 'Event slug' },
|
||||
outcome: { type: 'string', description: 'Outcome name' },
|
||||
outcomeIndex: { type: 'number', description: 'Outcome index' },
|
||||
name: { type: 'string', description: 'Trader name' },
|
||||
pseudonym: { type: 'string', description: 'Trader pseudonym' },
|
||||
bio: { type: 'string', description: 'Trader bio' },
|
||||
profileImage: { type: 'string', description: 'Profile image URL' },
|
||||
profileImageOptimized: { type: 'string', description: 'Optimized profile image URL' },
|
||||
transactionHash: { type: 'string', description: 'Transaction hash' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
export * from './get_event'
|
||||
export * from './get_events'
|
||||
export * from './get_last_trade_price'
|
||||
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'
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
import type { PolymarketSearchResult } from '@/tools/polymarket/types'
|
||||
import { buildGammaUrl, handlePolymarketError } from '@/tools/polymarket/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
import type { PolymarketPaginationParams, PolymarketSearchResult } from './types'
|
||||
import { buildGammaUrl, handlePolymarketError } from './types'
|
||||
|
||||
export interface PolymarketSearchParams extends PolymarketPaginationParams {
|
||||
query: string // Search term (required)
|
||||
export interface PolymarketSearchParams {
|
||||
query: string
|
||||
limit?: string
|
||||
page?: string
|
||||
cache?: string
|
||||
eventsStatus?: string
|
||||
limitPerType?: string
|
||||
eventsTag?: string
|
||||
sort?: string
|
||||
ascending?: string
|
||||
searchTags?: string
|
||||
searchProfiles?: string
|
||||
recurrence?: string
|
||||
excludeTagId?: string
|
||||
keepClosedMarkets?: string
|
||||
}
|
||||
|
||||
export interface PolymarketSearchResponse {
|
||||
@@ -32,10 +45,76 @@ export const polymarketSearchTool: ToolConfig<PolymarketSearchParams, Polymarket
|
||||
description: 'Number of results per page (max 50)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
offset: {
|
||||
page: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Pagination offset',
|
||||
description: 'Page number for pagination (1-indexed)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
cache: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Enable caching (true/false)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
eventsStatus: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Filter events by status',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
limitPerType: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Limit results per type (markets, events, profiles)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
eventsTag: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Filter by event tags (comma-separated)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
sort: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Sort field',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
ascending: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Sort direction (true for ascending, false for descending)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
searchTags: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Include tags in search results (true/false)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
searchProfiles: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Include profiles in search results (true/false)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
recurrence: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Filter by recurrence type',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
excludeTagId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Exclude events with these tag IDs (comma-separated)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
keepClosedMarkets: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
description: 'Include closed markets in results (0 or 1)',
|
||||
visibility: 'user-or-llm',
|
||||
},
|
||||
},
|
||||
@@ -44,9 +123,20 @@ export const polymarketSearchTool: ToolConfig<PolymarketSearchParams, Polymarket
|
||||
url: (params) => {
|
||||
const queryParams = new URLSearchParams()
|
||||
queryParams.append('q', params.query)
|
||||
// Default limit to 50 to prevent browser crashes from large data sets
|
||||
queryParams.append('limit', params.limit || '50')
|
||||
if (params.offset) queryParams.append('offset', params.offset)
|
||||
if (params.page) queryParams.append('page', params.page)
|
||||
if (params.cache) queryParams.append('cache', params.cache)
|
||||
if (params.eventsStatus) queryParams.append('events_status', params.eventsStatus)
|
||||
if (params.limitPerType) queryParams.append('limit_per_type', params.limitPerType)
|
||||
if (params.eventsTag) queryParams.append('events_tag', params.eventsTag)
|
||||
if (params.sort) queryParams.append('sort', params.sort)
|
||||
if (params.ascending) queryParams.append('ascending', params.ascending)
|
||||
if (params.searchTags) queryParams.append('search_tags', params.searchTags)
|
||||
if (params.searchProfiles) queryParams.append('search_profiles', params.searchProfiles)
|
||||
if (params.recurrence) queryParams.append('recurrence', params.recurrence)
|
||||
if (params.excludeTagId) queryParams.append('exclude_tag_id', params.excludeTagId)
|
||||
if (params.keepClosedMarkets)
|
||||
queryParams.append('keep_closed_markets', params.keepClosedMarkets)
|
||||
|
||||
return `${buildGammaUrl('/public-search')}?${queryParams.toString()}`
|
||||
},
|
||||
@@ -63,11 +153,11 @@ export const polymarketSearchTool: ToolConfig<PolymarketSearchParams, Polymarket
|
||||
handlePolymarketError(data, response.status, 'search')
|
||||
}
|
||||
|
||||
// Response contains markets, events, and profiles arrays
|
||||
const results: PolymarketSearchResult = {
|
||||
markets: data.markets || [],
|
||||
events: data.events || [],
|
||||
profiles: data.profiles || [],
|
||||
markets: data.markets ?? [],
|
||||
events: data.events ?? [],
|
||||
tags: data.tags ?? [],
|
||||
profiles: data.profiles ?? [],
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -81,7 +171,13 @@ export const polymarketSearchTool: ToolConfig<PolymarketSearchParams, Polymarket
|
||||
outputs: {
|
||||
results: {
|
||||
type: 'object',
|
||||
description: 'Search results containing markets, events, and profiles arrays',
|
||||
description: 'Search results containing markets, events, tags, and profiles arrays',
|
||||
properties: {
|
||||
markets: { type: 'array', description: 'Array of matching market objects' },
|
||||
events: { type: 'array', description: 'Array of matching event objects' },
|
||||
tags: { type: 'array', description: 'Array of matching tag objects' },
|
||||
profiles: { type: 'array', description: 'Array of matching profile objects' },
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -92,6 +92,11 @@ export interface PolymarketTag {
|
||||
id: string
|
||||
label: string
|
||||
slug: string
|
||||
createdAt?: string
|
||||
updatedAt?: string
|
||||
forceShow?: boolean
|
||||
forceHide?: boolean
|
||||
isCarousel?: boolean
|
||||
}
|
||||
|
||||
export interface PolymarketOrderBookEntry {
|
||||
@@ -106,11 +111,13 @@ export interface PolymarketOrderBook {
|
||||
timestamp: string
|
||||
bids: PolymarketOrderBookEntry[]
|
||||
asks: PolymarketOrderBookEntry[]
|
||||
min_order_size: string
|
||||
tick_size: string
|
||||
neg_risk: boolean
|
||||
}
|
||||
|
||||
export interface PolymarketPrice {
|
||||
price: string
|
||||
side: string
|
||||
}
|
||||
|
||||
export interface PolymarketPriceHistoryEntry {
|
||||
@@ -143,31 +150,125 @@ export interface PolymarketSeries {
|
||||
export interface PolymarketSearchResult {
|
||||
markets: PolymarketMarket[]
|
||||
events: PolymarketEvent[]
|
||||
profiles: any[]
|
||||
tags: PolymarketTag[]
|
||||
profiles: PolymarketProfile[]
|
||||
}
|
||||
|
||||
export interface PolymarketProfile {
|
||||
id: string
|
||||
name: string | null
|
||||
pseudonym: string | null
|
||||
bio: string | null
|
||||
profileImage: string | null
|
||||
profileImageOptimized: string | null
|
||||
walletAddress: string
|
||||
}
|
||||
|
||||
export interface PolymarketSpread {
|
||||
bid: string
|
||||
ask: string
|
||||
spread: string
|
||||
}
|
||||
|
||||
export interface PolymarketPosition {
|
||||
market: string
|
||||
asset_id: string
|
||||
size: string
|
||||
value: string
|
||||
proxyWallet: string | null
|
||||
asset: string
|
||||
conditionId: string
|
||||
size: number
|
||||
avgPrice: number
|
||||
initialValue: number
|
||||
currentValue: number
|
||||
cashPnl: number
|
||||
percentPnl: number
|
||||
totalBought: number
|
||||
realizedPnl: number
|
||||
percentRealizedPnl: number
|
||||
curPrice: number
|
||||
redeemable: boolean
|
||||
mergeable: boolean
|
||||
title: string | null
|
||||
slug: string | null
|
||||
icon: string | null
|
||||
eventSlug: string | null
|
||||
outcome: string | null
|
||||
outcomeIndex: number | null
|
||||
oppositeOutcome: string | null
|
||||
oppositeAsset: string | null
|
||||
endDate: string | null
|
||||
negativeRisk: boolean
|
||||
}
|
||||
|
||||
export interface PolymarketTrade {
|
||||
id: string
|
||||
market: string
|
||||
asset_id: string
|
||||
proxyWallet: string | null
|
||||
side: string
|
||||
size: string
|
||||
price: string
|
||||
timestamp: string
|
||||
maker: string
|
||||
taker: string
|
||||
asset: string
|
||||
conditionId: string
|
||||
size: number
|
||||
price: number
|
||||
timestamp: number
|
||||
title: string | null
|
||||
slug: string | null
|
||||
icon: string | null
|
||||
eventSlug: string | null
|
||||
outcome: string | null
|
||||
outcomeIndex: number | null
|
||||
name: string | null
|
||||
pseudonym: string | null
|
||||
bio: string | null
|
||||
profileImage: string | null
|
||||
profileImageOptimized: string | null
|
||||
transactionHash: string | null
|
||||
}
|
||||
|
||||
export interface PolymarketActivity {
|
||||
proxyWallet: string | null
|
||||
timestamp: number
|
||||
conditionId: string
|
||||
type: string
|
||||
size: number
|
||||
usdcSize: number
|
||||
transactionHash: string | null
|
||||
price: number | null
|
||||
asset: string | null
|
||||
side: string | null
|
||||
outcomeIndex: number | null
|
||||
title: string | null
|
||||
slug: string | null
|
||||
icon: string | null
|
||||
eventSlug: string | null
|
||||
outcome: string | null
|
||||
name: string | null
|
||||
pseudonym: string | null
|
||||
bio: string | null
|
||||
profileImage: string | null
|
||||
profileImageOptimized: string | null
|
||||
}
|
||||
|
||||
export interface PolymarketLeaderboardEntry {
|
||||
rank: string
|
||||
proxyWallet: string
|
||||
userName: string | null
|
||||
vol: number
|
||||
pnl: number
|
||||
profileImage: string | null
|
||||
xUsername: string | null
|
||||
verifiedBadge: boolean
|
||||
}
|
||||
|
||||
export interface PolymarketHolder {
|
||||
proxyWallet: string
|
||||
bio: string | null
|
||||
asset: string
|
||||
pseudonym: string | null
|
||||
amount: number
|
||||
displayUsernamePublic: boolean
|
||||
outcomeIndex: number
|
||||
name: string | null
|
||||
profileImage: string | null
|
||||
profileImageOptimized: string | null
|
||||
}
|
||||
|
||||
export interface PolymarketMarketHolders {
|
||||
token: string
|
||||
holders: PolymarketHolder[]
|
||||
}
|
||||
|
||||
export function handlePolymarketError(data: any, status: number, operation: string): never {
|
||||
|
||||
@@ -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 {
|
||||
@@ -746,22 +761,39 @@ import {
|
||||
} from '@/tools/jsm'
|
||||
import {
|
||||
kalshiAmendOrderTool,
|
||||
kalshiAmendOrderV2Tool,
|
||||
kalshiCancelOrderTool,
|
||||
kalshiCancelOrderV2Tool,
|
||||
kalshiCreateOrderTool,
|
||||
kalshiCreateOrderV2Tool,
|
||||
kalshiGetBalanceTool,
|
||||
kalshiGetBalanceV2Tool,
|
||||
kalshiGetCandlesticksTool,
|
||||
kalshiGetCandlesticksV2Tool,
|
||||
kalshiGetEventsTool,
|
||||
kalshiGetEventsV2Tool,
|
||||
kalshiGetEventTool,
|
||||
kalshiGetEventV2Tool,
|
||||
kalshiGetExchangeStatusTool,
|
||||
kalshiGetExchangeStatusV2Tool,
|
||||
kalshiGetFillsTool,
|
||||
kalshiGetFillsV2Tool,
|
||||
kalshiGetMarketsTool,
|
||||
kalshiGetMarketsV2Tool,
|
||||
kalshiGetMarketTool,
|
||||
kalshiGetMarketV2Tool,
|
||||
kalshiGetOrderbookTool,
|
||||
kalshiGetOrderbookV2Tool,
|
||||
kalshiGetOrdersTool,
|
||||
kalshiGetOrdersV2Tool,
|
||||
kalshiGetOrderTool,
|
||||
kalshiGetOrderV2Tool,
|
||||
kalshiGetPositionsTool,
|
||||
kalshiGetPositionsV2Tool,
|
||||
kalshiGetSeriesByTickerTool,
|
||||
kalshiGetSeriesByTickerV2Tool,
|
||||
kalshiGetTradesTool,
|
||||
kalshiGetTradesV2Tool,
|
||||
} from '@/tools/kalshi'
|
||||
import {
|
||||
knowledgeCreateDocumentTool,
|
||||
@@ -1072,9 +1104,12 @@ import {
|
||||
pipedriveUpdateLeadTool,
|
||||
} from '@/tools/pipedrive'
|
||||
import {
|
||||
polymarketGetActivityTool,
|
||||
polymarketGetEventsTool,
|
||||
polymarketGetEventTool,
|
||||
polymarketGetHoldersTool,
|
||||
polymarketGetLastTradePriceTool,
|
||||
polymarketGetLeaderboardTool,
|
||||
polymarketGetMarketsTool,
|
||||
polymarketGetMarketTool,
|
||||
polymarketGetMidpointTool,
|
||||
@@ -1815,22 +1850,39 @@ export const tools: Record<string, ToolConfig> = {
|
||||
jsm_get_approvals: jsmGetApprovalsTool,
|
||||
jsm_answer_approval: jsmAnswerApprovalTool,
|
||||
kalshi_get_markets: kalshiGetMarketsTool,
|
||||
kalshi_get_markets_v2: kalshiGetMarketsV2Tool,
|
||||
kalshi_get_market: kalshiGetMarketTool,
|
||||
kalshi_get_market_v2: kalshiGetMarketV2Tool,
|
||||
kalshi_get_events: kalshiGetEventsTool,
|
||||
kalshi_get_events_v2: kalshiGetEventsV2Tool,
|
||||
kalshi_get_event: kalshiGetEventTool,
|
||||
kalshi_get_event_v2: kalshiGetEventV2Tool,
|
||||
kalshi_get_balance: kalshiGetBalanceTool,
|
||||
kalshi_get_balance_v2: kalshiGetBalanceV2Tool,
|
||||
kalshi_get_positions: kalshiGetPositionsTool,
|
||||
kalshi_get_positions_v2: kalshiGetPositionsV2Tool,
|
||||
kalshi_get_orders: kalshiGetOrdersTool,
|
||||
kalshi_get_orders_v2: kalshiGetOrdersV2Tool,
|
||||
kalshi_get_order: kalshiGetOrderTool,
|
||||
kalshi_get_order_v2: kalshiGetOrderV2Tool,
|
||||
kalshi_get_orderbook: kalshiGetOrderbookTool,
|
||||
kalshi_get_orderbook_v2: kalshiGetOrderbookV2Tool,
|
||||
kalshi_get_trades: kalshiGetTradesTool,
|
||||
kalshi_get_trades_v2: kalshiGetTradesV2Tool,
|
||||
kalshi_get_candlesticks: kalshiGetCandlesticksTool,
|
||||
kalshi_get_candlesticks_v2: kalshiGetCandlesticksV2Tool,
|
||||
kalshi_get_fills: kalshiGetFillsTool,
|
||||
kalshi_get_fills_v2: kalshiGetFillsV2Tool,
|
||||
kalshi_get_series_by_ticker: kalshiGetSeriesByTickerTool,
|
||||
kalshi_get_series_by_ticker_v2: kalshiGetSeriesByTickerV2Tool,
|
||||
kalshi_get_exchange_status: kalshiGetExchangeStatusTool,
|
||||
kalshi_get_exchange_status_v2: kalshiGetExchangeStatusV2Tool,
|
||||
kalshi_create_order: kalshiCreateOrderTool,
|
||||
kalshi_create_order_v2: kalshiCreateOrderV2Tool,
|
||||
kalshi_cancel_order: kalshiCancelOrderTool,
|
||||
kalshi_cancel_order_v2: kalshiCancelOrderV2Tool,
|
||||
kalshi_amend_order: kalshiAmendOrderTool,
|
||||
kalshi_amend_order_v2: kalshiAmendOrderV2Tool,
|
||||
polymarket_get_markets: polymarketGetMarketsTool,
|
||||
polymarket_get_market: polymarketGetMarketTool,
|
||||
polymarket_get_events: polymarketGetEventsTool,
|
||||
@@ -1848,6 +1900,9 @@ export const tools: Record<string, ToolConfig> = {
|
||||
polymarket_get_tick_size: polymarketGetTickSizeTool,
|
||||
polymarket_get_positions: polymarketGetPositionsTool,
|
||||
polymarket_get_trades: polymarketGetTradesTool,
|
||||
polymarket_get_activity: polymarketGetActivityTool,
|
||||
polymarket_get_leaderboard: polymarketGetLeaderboardTool,
|
||||
polymarket_get_holders: polymarketGetHoldersTool,
|
||||
slack_message: slackMessageTool,
|
||||
slack_message_reader: slackMessageReaderTool,
|
||||
slack_list_channels: slackListChannelsTool,
|
||||
@@ -3086,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,
|
||||
|
||||
Reference in New Issue
Block a user