mirror of
https://github.com/simstudioai/sim.git
synced 2026-02-18 02:11:59 -05:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da46a387c9 | ||
|
|
a0afb5d03e | ||
|
|
cdacb796a8 | ||
|
|
3ce54147e6 | ||
|
|
08690b2906 | ||
|
|
299cc26694 | ||
|
|
48715ff013 | ||
|
|
ad0d0ed1f1 | ||
|
|
b7e377ec4b |
@@ -59,12 +59,6 @@ body {
|
|||||||
--content-gap: 1.75rem;
|
--content-gap: 1.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove custom layout variable overrides to fallback to fumadocs defaults */
|
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
Navbar Light Mode Styling
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
/* Light mode navbar and search styling */
|
/* Light mode navbar and search styling */
|
||||||
:root:not(.dark) nav {
|
:root:not(.dark) nav {
|
||||||
background-color: hsla(0, 0%, 96%, 0.85) !important;
|
background-color: hsla(0, 0%, 96%, 0.85) !important;
|
||||||
@@ -88,10 +82,6 @@ body {
|
|||||||
-webkit-backdrop-filter: blur(25px) saturate(180%) brightness(0.6) !important;
|
-webkit-backdrop-filter: blur(25px) saturate(180%) brightness(0.6) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
Custom Sidebar Styling (Turborepo-inspired)
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
/* Floating sidebar appearance - remove background */
|
/* Floating sidebar appearance - remove background */
|
||||||
[data-sidebar-container],
|
[data-sidebar-container],
|
||||||
#nd-sidebar {
|
#nd-sidebar {
|
||||||
@@ -468,10 +458,6 @@ aside[data-sidebar],
|
|||||||
writing-mode: horizontal-tb !important;
|
writing-mode: horizontal-tb !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
Code Block Styling (Improved)
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
/* Apply Geist Mono to code elements */
|
/* Apply Geist Mono to code elements */
|
||||||
code,
|
code,
|
||||||
pre,
|
pre,
|
||||||
@@ -532,10 +518,6 @@ pre code .line {
|
|||||||
color: var(--color-fd-primary);
|
color: var(--color-fd-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
TOC (Table of Contents) Styling
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
/* Remove the thin border-left on nested TOC items (keeps main indicator only) */
|
/* Remove the thin border-left on nested TOC items (keeps main indicator only) */
|
||||||
#nd-toc a[style*="padding-inline-start"] {
|
#nd-toc a[style*="padding-inline-start"] {
|
||||||
border-left: none !important;
|
border-left: none !important;
|
||||||
@@ -554,10 +536,6 @@ main article,
|
|||||||
padding-bottom: 4rem;
|
padding-bottom: 4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ============================================
|
|
||||||
Center and Constrain Main Content Width
|
|
||||||
============================================ */
|
|
||||||
|
|
||||||
/* Main content area - center and constrain like turborepo/raindrop */
|
/* Main content area - center and constrain like turborepo/raindrop */
|
||||||
/* Note: --sidebar-offset and --toc-offset are now applied at #nd-docs-layout level */
|
/* Note: --sidebar-offset and --toc-offset are now applied at #nd-docs-layout level */
|
||||||
main[data-main] {
|
main[data-main] {
|
||||||
|
|||||||
@@ -234,7 +234,6 @@ List actions from incident.io. Optionally filter by incident ID.
|
|||||||
| --------- | ---- | -------- | ----------- |
|
| --------- | ---- | -------- | ----------- |
|
||||||
| `apiKey` | string | Yes | incident.io API Key |
|
| `apiKey` | string | Yes | incident.io API Key |
|
||||||
| `incident_id` | string | No | Filter actions by incident ID \(e.g., "01FCNDV6P870EA6S7TK1DSYDG0"\) |
|
| `incident_id` | string | No | Filter actions by incident ID \(e.g., "01FCNDV6P870EA6S7TK1DSYDG0"\) |
|
||||||
| `page_size` | number | No | Number of actions to return per page \(e.g., 10, 25, 50\) |
|
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|
||||||
@@ -309,7 +308,6 @@ List follow-ups from incident.io. Optionally filter by incident ID.
|
|||||||
| --------- | ---- | -------- | ----------- |
|
| --------- | ---- | -------- | ----------- |
|
||||||
| `apiKey` | string | Yes | incident.io API Key |
|
| `apiKey` | string | Yes | incident.io API Key |
|
||||||
| `incident_id` | string | No | Filter follow-ups by incident ID \(e.g., "01FCNDV6P870EA6S7TK1DSYDG0"\) |
|
| `incident_id` | string | No | Filter follow-ups by incident ID \(e.g., "01FCNDV6P870EA6S7TK1DSYDG0"\) |
|
||||||
| `page_size` | number | No | Number of follow-ups to return per page \(e.g., 10, 25, 50\) |
|
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|
||||||
@@ -396,6 +394,7 @@ List all users in your Incident.io workspace. Returns user details including id,
|
|||||||
| --------- | ---- | -------- | ----------- |
|
| --------- | ---- | -------- | ----------- |
|
||||||
| `apiKey` | string | Yes | Incident.io API Key |
|
| `apiKey` | string | Yes | Incident.io API Key |
|
||||||
| `page_size` | number | No | Number of results to return per page \(e.g., 10, 25, 50\). Default: 25 |
|
| `page_size` | number | No | Number of results to return per page \(e.g., 10, 25, 50\). Default: 25 |
|
||||||
|
| `after` | string | No | Pagination cursor to fetch the next page of results |
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|
||||||
@@ -406,6 +405,10 @@ List all users in your Incident.io workspace. Returns user details including id,
|
|||||||
| ↳ `name` | string | Full name of the user |
|
| ↳ `name` | string | Full name of the user |
|
||||||
| ↳ `email` | string | Email address of the user |
|
| ↳ `email` | string | Email address of the user |
|
||||||
| ↳ `role` | string | Role of the user in the workspace |
|
| ↳ `role` | string | Role of the user in the workspace |
|
||||||
|
| `pagination_meta` | object | Pagination metadata |
|
||||||
|
| ↳ `after` | string | Cursor for next page |
|
||||||
|
| ↳ `page_size` | number | Number of items per page |
|
||||||
|
| ↳ `total_record_count` | number | Total number of records |
|
||||||
|
|
||||||
### `incidentio_users_show`
|
### `incidentio_users_show`
|
||||||
|
|
||||||
@@ -644,7 +647,6 @@ List all escalation policies in incident.io
|
|||||||
| Parameter | Type | Required | Description |
|
| Parameter | Type | Required | Description |
|
||||||
| --------- | ---- | -------- | ----------- |
|
| --------- | ---- | -------- | ----------- |
|
||||||
| `apiKey` | string | Yes | incident.io API Key |
|
| `apiKey` | string | Yes | incident.io API Key |
|
||||||
| `page_size` | number | No | Number of results per page \(e.g., 10, 25, 50\). Default: 25 |
|
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ Retrieve all deals from Pipedrive with optional filters
|
|||||||
| `pipeline_id` | string | No | If supplied, only deals in the specified pipeline are returned \(e.g., "1"\) |
|
| `pipeline_id` | string | No | If supplied, only deals in the specified pipeline are returned \(e.g., "1"\) |
|
||||||
| `updated_since` | string | No | If set, only deals updated after this time are returned. Format: 2025-01-01T10:20:00Z |
|
| `updated_since` | string | No | If set, only deals updated after this time are returned. Format: 2025-01-01T10:20:00Z |
|
||||||
| `limit` | string | No | Number of results to return \(e.g., "50", default: 100, max: 500\) |
|
| `limit` | string | No | Number of results to return \(e.g., "50", default: 100, max: 500\) |
|
||||||
|
| `cursor` | string | No | For pagination, the marker representing the first item on the next page |
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|
||||||
@@ -74,6 +75,8 @@ Retrieve all deals from Pipedrive with optional filters
|
|||||||
| `metadata` | object | Pagination metadata for the response |
|
| `metadata` | object | Pagination metadata for the response |
|
||||||
| ↳ `total_items` | number | Total number of items |
|
| ↳ `total_items` | number | Total number of items |
|
||||||
| ↳ `has_more` | boolean | Whether more items are available |
|
| ↳ `has_more` | boolean | Whether more items are available |
|
||||||
|
| ↳ `next_cursor` | string | Cursor for fetching the next page \(v2 endpoints\) |
|
||||||
|
| ↳ `next_start` | number | Offset for fetching the next page \(v1 endpoints\) |
|
||||||
| `success` | boolean | Operation success status |
|
| `success` | boolean | Operation success status |
|
||||||
|
|
||||||
### `pipedrive_get_deal`
|
### `pipedrive_get_deal`
|
||||||
@@ -148,10 +151,9 @@ Retrieve files from Pipedrive with optional filters
|
|||||||
|
|
||||||
| Parameter | Type | Required | Description |
|
| Parameter | Type | Required | Description |
|
||||||
| --------- | ---- | -------- | ----------- |
|
| --------- | ---- | -------- | ----------- |
|
||||||
| `deal_id` | string | No | Filter files by deal ID \(e.g., "123"\) |
|
| `sort` | string | No | Sort files by field \(supported: "id", "update_time"\) |
|
||||||
| `person_id` | string | No | Filter files by person ID \(e.g., "456"\) |
|
| `limit` | string | No | Number of results to return \(e.g., "50", default: 100, max: 100\) |
|
||||||
| `org_id` | string | No | Filter files by organization ID \(e.g., "789"\) |
|
| `start` | string | No | Pagination start offset \(0-based index of the first item to return\) |
|
||||||
| `limit` | string | No | Number of results to return \(e.g., "50", default: 100, max: 500\) |
|
|
||||||
| `downloadFiles` | boolean | No | Download file contents into file outputs |
|
| `downloadFiles` | boolean | No | Download file contents into file outputs |
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
@@ -171,6 +173,8 @@ Retrieve files from Pipedrive with optional filters
|
|||||||
| ↳ `url` | string | File download URL |
|
| ↳ `url` | string | File download URL |
|
||||||
| `downloadedFiles` | file[] | Downloaded files from Pipedrive |
|
| `downloadedFiles` | file[] | Downloaded files from Pipedrive |
|
||||||
| `total_items` | number | Total number of files returned |
|
| `total_items` | number | Total number of files returned |
|
||||||
|
| `has_more` | boolean | Whether more files are available |
|
||||||
|
| `next_start` | number | Offset for fetching the next page |
|
||||||
| `success` | boolean | Operation success status |
|
| `success` | boolean | Operation success status |
|
||||||
|
|
||||||
### `pipedrive_get_mail_messages`
|
### `pipedrive_get_mail_messages`
|
||||||
@@ -183,6 +187,7 @@ Retrieve mail threads from Pipedrive mailbox
|
|||||||
| --------- | ---- | -------- | ----------- |
|
| --------- | ---- | -------- | ----------- |
|
||||||
| `folder` | string | No | Filter by folder: inbox, drafts, sent, archive \(default: inbox\) |
|
| `folder` | string | No | Filter by folder: inbox, drafts, sent, archive \(default: inbox\) |
|
||||||
| `limit` | string | No | Number of results to return \(e.g., "25", default: 50\) |
|
| `limit` | string | No | Number of results to return \(e.g., "25", default: 50\) |
|
||||||
|
| `start` | string | No | Pagination start offset \(0-based index of the first item to return\) |
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|
||||||
@@ -190,6 +195,8 @@ Retrieve mail threads from Pipedrive mailbox
|
|||||||
| --------- | ---- | ----------- |
|
| --------- | ---- | ----------- |
|
||||||
| `messages` | array | Array of mail thread objects from Pipedrive mailbox |
|
| `messages` | array | Array of mail thread objects from Pipedrive mailbox |
|
||||||
| `total_items` | number | Total number of mail threads returned |
|
| `total_items` | number | Total number of mail threads returned |
|
||||||
|
| `has_more` | boolean | Whether more messages are available |
|
||||||
|
| `next_start` | number | Offset for fetching the next page |
|
||||||
| `success` | boolean | Operation success status |
|
| `success` | boolean | Operation success status |
|
||||||
|
|
||||||
### `pipedrive_get_mail_thread`
|
### `pipedrive_get_mail_thread`
|
||||||
@@ -221,7 +228,7 @@ Retrieve all pipelines from Pipedrive
|
|||||||
| `sort_by` | string | No | Field to sort by: id, update_time, add_time \(default: id\) |
|
| `sort_by` | string | No | Field to sort by: id, update_time, add_time \(default: id\) |
|
||||||
| `sort_direction` | string | No | Sorting direction: asc, desc \(default: asc\) |
|
| `sort_direction` | string | No | Sorting direction: asc, desc \(default: asc\) |
|
||||||
| `limit` | string | No | Number of results to return \(e.g., "50", default: 100, max: 500\) |
|
| `limit` | string | No | Number of results to return \(e.g., "50", default: 100, max: 500\) |
|
||||||
| `cursor` | string | No | For pagination, the marker representing the first item on the next page |
|
| `start` | string | No | Pagination start offset \(0-based index of the first item to return\) |
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|
||||||
@@ -237,6 +244,8 @@ Retrieve all pipelines from Pipedrive
|
|||||||
| ↳ `add_time` | string | When the pipeline was created |
|
| ↳ `add_time` | string | When the pipeline was created |
|
||||||
| ↳ `update_time` | string | When the pipeline was last updated |
|
| ↳ `update_time` | string | When the pipeline was last updated |
|
||||||
| `total_items` | number | Total number of pipelines returned |
|
| `total_items` | number | Total number of pipelines returned |
|
||||||
|
| `has_more` | boolean | Whether more pipelines are available |
|
||||||
|
| `next_start` | number | Offset for fetching the next page |
|
||||||
| `success` | boolean | Operation success status |
|
| `success` | boolean | Operation success status |
|
||||||
|
|
||||||
### `pipedrive_get_pipeline_deals`
|
### `pipedrive_get_pipeline_deals`
|
||||||
@@ -249,8 +258,8 @@ Retrieve all deals in a specific pipeline
|
|||||||
| --------- | ---- | -------- | ----------- |
|
| --------- | ---- | -------- | ----------- |
|
||||||
| `pipeline_id` | string | Yes | The ID of the pipeline \(e.g., "1"\) |
|
| `pipeline_id` | string | Yes | The ID of the pipeline \(e.g., "1"\) |
|
||||||
| `stage_id` | string | No | Filter by specific stage within the pipeline \(e.g., "2"\) |
|
| `stage_id` | string | No | Filter by specific stage within the pipeline \(e.g., "2"\) |
|
||||||
| `status` | string | No | Filter by deal status: open, won, lost |
|
|
||||||
| `limit` | string | No | Number of results to return \(e.g., "50", default: 100, max: 500\) |
|
| `limit` | string | No | Number of results to return \(e.g., "50", default: 100, max: 500\) |
|
||||||
|
| `start` | string | No | Pagination start offset \(0-based index of the first item to return\) |
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|
||||||
@@ -271,6 +280,7 @@ Retrieve all projects or a specific project from Pipedrive
|
|||||||
| `project_id` | string | No | Optional: ID of a specific project to retrieve \(e.g., "123"\) |
|
| `project_id` | string | No | Optional: ID of a specific project to retrieve \(e.g., "123"\) |
|
||||||
| `status` | string | No | Filter by project status: open, completed, deleted \(only for listing all\) |
|
| `status` | string | No | Filter by project status: open, completed, deleted \(only for listing all\) |
|
||||||
| `limit` | string | No | Number of results to return \(e.g., "50", default: 100, max: 500, only for listing all\) |
|
| `limit` | string | No | Number of results to return \(e.g., "50", default: 100, max: 500, only for listing all\) |
|
||||||
|
| `cursor` | string | No | For pagination, the marker representing the first item on the next page |
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|
||||||
@@ -279,6 +289,8 @@ Retrieve all projects or a specific project from Pipedrive
|
|||||||
| `projects` | array | Array of project objects \(when listing all\) |
|
| `projects` | array | Array of project objects \(when listing all\) |
|
||||||
| `project` | object | Single project object \(when project_id is provided\) |
|
| `project` | object | Single project object \(when project_id is provided\) |
|
||||||
| `total_items` | number | Total number of projects returned |
|
| `total_items` | number | Total number of projects returned |
|
||||||
|
| `has_more` | boolean | Whether more projects are available |
|
||||||
|
| `next_cursor` | string | Cursor for fetching the next page |
|
||||||
| `success` | boolean | Operation success status |
|
| `success` | boolean | Operation success status |
|
||||||
|
|
||||||
### `pipedrive_create_project`
|
### `pipedrive_create_project`
|
||||||
@@ -309,12 +321,11 @@ Retrieve activities (tasks) from Pipedrive with optional filters
|
|||||||
|
|
||||||
| Parameter | Type | Required | Description |
|
| Parameter | Type | Required | Description |
|
||||||
| --------- | ---- | -------- | ----------- |
|
| --------- | ---- | -------- | ----------- |
|
||||||
| `deal_id` | string | No | Filter activities by deal ID \(e.g., "123"\) |
|
| `user_id` | string | No | Filter activities by user ID \(e.g., "123"\) |
|
||||||
| `person_id` | string | No | Filter activities by person ID \(e.g., "456"\) |
|
|
||||||
| `org_id` | string | No | Filter activities by organization ID \(e.g., "789"\) |
|
|
||||||
| `type` | string | No | Filter by activity type \(call, meeting, task, deadline, email, lunch\) |
|
| `type` | string | No | Filter by activity type \(call, meeting, task, deadline, email, lunch\) |
|
||||||
| `done` | string | No | Filter by completion status: 0 for not done, 1 for done |
|
| `done` | string | No | Filter by completion status: 0 for not done, 1 for done |
|
||||||
| `limit` | string | No | Number of results to return \(e.g., "50", default: 100, max: 500\) |
|
| `limit` | string | No | Number of results to return \(e.g., "50", default: 100, max: 500\) |
|
||||||
|
| `start` | string | No | Pagination start offset \(0-based index of the first item to return\) |
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|
||||||
@@ -335,6 +346,8 @@ Retrieve activities (tasks) from Pipedrive with optional filters
|
|||||||
| ↳ `add_time` | string | When the activity was created |
|
| ↳ `add_time` | string | When the activity was created |
|
||||||
| ↳ `update_time` | string | When the activity was last updated |
|
| ↳ `update_time` | string | When the activity was last updated |
|
||||||
| `total_items` | number | Total number of activities returned |
|
| `total_items` | number | Total number of activities returned |
|
||||||
|
| `has_more` | boolean | Whether more activities are available |
|
||||||
|
| `next_start` | number | Offset for fetching the next page |
|
||||||
| `success` | boolean | Operation success status |
|
| `success` | boolean | Operation success status |
|
||||||
|
|
||||||
### `pipedrive_create_activity`
|
### `pipedrive_create_activity`
|
||||||
@@ -399,6 +412,7 @@ Retrieve all leads or a specific lead from Pipedrive
|
|||||||
| `person_id` | string | No | Filter by person ID \(e.g., "456"\) |
|
| `person_id` | string | No | Filter by person ID \(e.g., "456"\) |
|
||||||
| `organization_id` | string | No | Filter by organization ID \(e.g., "789"\) |
|
| `organization_id` | string | No | Filter by organization ID \(e.g., "789"\) |
|
||||||
| `limit` | string | No | Number of results to return \(e.g., "50", default: 100, max: 500\) |
|
| `limit` | string | No | Number of results to return \(e.g., "50", default: 100, max: 500\) |
|
||||||
|
| `start` | string | No | Pagination start offset \(0-based index of the first item to return\) |
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|
||||||
@@ -433,6 +447,8 @@ Retrieve all leads or a specific lead from Pipedrive
|
|||||||
| ↳ `add_time` | string | When the lead was created \(ISO 8601\) |
|
| ↳ `add_time` | string | When the lead was created \(ISO 8601\) |
|
||||||
| ↳ `update_time` | string | When the lead was last updated \(ISO 8601\) |
|
| ↳ `update_time` | string | When the lead was last updated \(ISO 8601\) |
|
||||||
| `total_items` | number | Total number of leads returned |
|
| `total_items` | number | Total number of leads returned |
|
||||||
|
| `has_more` | boolean | Whether more leads are available |
|
||||||
|
| `next_start` | number | Offset for fetching the next page |
|
||||||
| `success` | boolean | Operation success status |
|
| `success` | boolean | Operation success status |
|
||||||
|
|
||||||
### `pipedrive_create_lead`
|
### `pipedrive_create_lead`
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ Query data from a Supabase table
|
|||||||
| `filter` | string | No | PostgREST filter \(e.g., "id=eq.123"\) |
|
| `filter` | string | No | PostgREST filter \(e.g., "id=eq.123"\) |
|
||||||
| `orderBy` | string | No | Column to order by \(add DESC for descending\) |
|
| `orderBy` | string | No | Column to order by \(add DESC for descending\) |
|
||||||
| `limit` | number | No | Maximum number of rows to return |
|
| `limit` | number | No | Maximum number of rows to return |
|
||||||
|
| `offset` | number | No | Number of rows to skip \(for pagination\) |
|
||||||
| `apiKey` | string | Yes | Your Supabase service role secret key |
|
| `apiKey` | string | Yes | Your Supabase service role secret key |
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
@@ -211,6 +212,7 @@ Perform full-text search on a Supabase table
|
|||||||
| `searchType` | string | No | Search type: plain, phrase, or websearch \(default: websearch\) |
|
| `searchType` | string | No | Search type: plain, phrase, or websearch \(default: websearch\) |
|
||||||
| `language` | string | No | Language for text search configuration \(default: english\) |
|
| `language` | string | No | Language for text search configuration \(default: english\) |
|
||||||
| `limit` | number | No | Maximum number of rows to return |
|
| `limit` | number | No | Maximum number of rows to return |
|
||||||
|
| `offset` | number | No | Number of rows to skip \(for pagination\) |
|
||||||
| `apiKey` | string | Yes | Your Supabase service role secret key |
|
| `apiKey` | string | Yes | Your Supabase service role secret key |
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ Retrieve form responses from Typeform
|
|||||||
| `formId` | string | Yes | Typeform form ID \(e.g., "abc123XYZ"\) |
|
| `formId` | string | Yes | Typeform form ID \(e.g., "abc123XYZ"\) |
|
||||||
| `apiKey` | string | Yes | Typeform Personal Access Token |
|
| `apiKey` | string | Yes | Typeform Personal Access Token |
|
||||||
| `pageSize` | number | No | Number of responses to retrieve \(e.g., 10, 25, 50\) |
|
| `pageSize` | number | No | Number of responses to retrieve \(e.g., 10, 25, 50\) |
|
||||||
|
| `before` | string | No | Cursor token for fetching the next page of older responses |
|
||||||
|
| `after` | string | No | Cursor token for fetching the next page of newer responses |
|
||||||
| `since` | string | No | Retrieve responses submitted after this date \(e.g., "2024-01-01T00:00:00Z"\) |
|
| `since` | string | No | Retrieve responses submitted after this date \(e.g., "2024-01-01T00:00:00Z"\) |
|
||||||
| `until` | string | No | Retrieve responses submitted before this date \(e.g., "2024-12-31T23:59:59Z"\) |
|
| `until` | string | No | Retrieve responses submitted before this date \(e.g., "2024-12-31T23:59:59Z"\) |
|
||||||
| `completed` | string | No | Filter by completion status \(e.g., "true", "false", "all"\) |
|
| `completed` | string | No | Filter by completion status \(e.g., "true", "false", "all"\) |
|
||||||
|
|||||||
@@ -67,10 +67,9 @@ Retrieve a list of tickets from Zendesk with optional filtering
|
|||||||
| `type` | string | No | Filter by type: "problem", "incident", "question", or "task" |
|
| `type` | string | No | Filter by type: "problem", "incident", "question", or "task" |
|
||||||
| `assigneeId` | string | No | Filter by assignee user ID as a numeric string \(e.g., "12345"\) |
|
| `assigneeId` | string | No | Filter by assignee user ID as a numeric string \(e.g., "12345"\) |
|
||||||
| `organizationId` | string | No | Filter by organization ID as a numeric string \(e.g., "67890"\) |
|
| `organizationId` | string | No | Filter by organization ID as a numeric string \(e.g., "67890"\) |
|
||||||
| `sortBy` | string | No | Sort field: "created_at", "updated_at", "priority", or "status" |
|
| `sort` | string | No | Sort field for ticket listing \(only applies without filters\): "updated_at", "id", or "status". Prefix with "-" for descending \(e.g., "-updated_at"\) |
|
||||||
| `sortOrder` | string | No | Sort order: "asc" or "desc" |
|
|
||||||
| `perPage` | string | No | Results per page as a number string \(default: "100", max: "100"\) |
|
| `perPage` | string | No | Results per page as a number string \(default: "100", max: "100"\) |
|
||||||
| `page` | string | No | Page number as a string \(e.g., "1", "2"\) |
|
| `pageAfter` | string | No | Cursor from a previous response to fetch the next page of results |
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|
||||||
@@ -129,10 +128,10 @@ Retrieve a list of tickets from Zendesk with optional filtering
|
|||||||
| ↳ `from_messaging_channel` | boolean | Whether the ticket originated from a messaging channel |
|
| ↳ `from_messaging_channel` | boolean | Whether the ticket originated from a messaging channel |
|
||||||
| ↳ `ticket_form_id` | number | Ticket form ID |
|
| ↳ `ticket_form_id` | number | Ticket form ID |
|
||||||
| ↳ `generated_timestamp` | number | Unix timestamp of the ticket generation |
|
| ↳ `generated_timestamp` | number | Unix timestamp of the ticket generation |
|
||||||
| `paging` | object | Pagination information |
|
| `paging` | object | Cursor-based pagination information |
|
||||||
|
| ↳ `after_cursor` | string | Cursor for fetching the next page of results |
|
||||||
|
| ↳ `has_more` | boolean | Whether more results are available |
|
||||||
| ↳ `next_page` | string | URL for next page of results |
|
| ↳ `next_page` | string | URL for next page of results |
|
||||||
| ↳ `previous_page` | string | URL for previous page of results |
|
|
||||||
| ↳ `count` | number | Total count of items |
|
|
||||||
| `metadata` | object | Response metadata |
|
| `metadata` | object | Response metadata |
|
||||||
| ↳ `total_returned` | number | Number of items returned in this response |
|
| ↳ `total_returned` | number | Number of items returned in this response |
|
||||||
| ↳ `has_more` | boolean | Whether more items are available |
|
| ↳ `has_more` | boolean | Whether more items are available |
|
||||||
@@ -515,7 +514,7 @@ Retrieve a list of users from Zendesk with optional filtering
|
|||||||
| `role` | string | No | Filter by role: "end-user", "agent", or "admin" |
|
| `role` | string | No | Filter by role: "end-user", "agent", or "admin" |
|
||||||
| `permissionSet` | string | No | Filter by permission set ID as a numeric string \(e.g., "12345"\) |
|
| `permissionSet` | string | No | Filter by permission set ID as a numeric string \(e.g., "12345"\) |
|
||||||
| `perPage` | string | No | Results per page as a number string \(default: "100", max: "100"\) |
|
| `perPage` | string | No | Results per page as a number string \(default: "100", max: "100"\) |
|
||||||
| `page` | string | No | Page number as a string \(e.g., "1", "2"\) |
|
| `pageAfter` | string | No | Cursor from a previous response to fetch the next page of results |
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|
||||||
@@ -563,10 +562,10 @@ Retrieve a list of users from Zendesk with optional filtering
|
|||||||
| ↳ `shared` | boolean | Whether the user is shared from a different Zendesk |
|
| ↳ `shared` | boolean | Whether the user is shared from a different Zendesk |
|
||||||
| ↳ `shared_agent` | boolean | Whether the agent is shared from a different Zendesk |
|
| ↳ `shared_agent` | boolean | Whether the agent is shared from a different Zendesk |
|
||||||
| ↳ `remote_photo_url` | string | URL to a remote photo |
|
| ↳ `remote_photo_url` | string | URL to a remote photo |
|
||||||
| `paging` | object | Pagination information |
|
| `paging` | object | Cursor-based pagination information |
|
||||||
|
| ↳ `after_cursor` | string | Cursor for fetching the next page of results |
|
||||||
|
| ↳ `has_more` | boolean | Whether more results are available |
|
||||||
| ↳ `next_page` | string | URL for next page of results |
|
| ↳ `next_page` | string | URL for next page of results |
|
||||||
| ↳ `previous_page` | string | URL for previous page of results |
|
|
||||||
| ↳ `count` | number | Total count of items |
|
|
||||||
| `metadata` | object | Response metadata |
|
| `metadata` | object | Response metadata |
|
||||||
| ↳ `total_returned` | number | Number of items returned in this response |
|
| ↳ `total_returned` | number | Number of items returned in this response |
|
||||||
| ↳ `has_more` | boolean | Whether more items are available |
|
| ↳ `has_more` | boolean | Whether more items are available |
|
||||||
@@ -706,7 +705,7 @@ Search for users in Zendesk using a query string
|
|||||||
| `query` | string | No | Search query string \(e.g., user name or email\) |
|
| `query` | string | No | Search query string \(e.g., user name or email\) |
|
||||||
| `externalId` | string | No | External ID to search by \(your system identifier\) |
|
| `externalId` | string | No | External ID to search by \(your system identifier\) |
|
||||||
| `perPage` | string | No | Results per page as a number string \(default: "100", max: "100"\) |
|
| `perPage` | string | No | Results per page as a number string \(default: "100", max: "100"\) |
|
||||||
| `page` | string | No | Page number as a string \(e.g., "1", "2"\) |
|
| `page` | string | No | Page number for pagination \(1-based\) |
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|
||||||
@@ -754,10 +753,10 @@ Search for users in Zendesk using a query string
|
|||||||
| ↳ `shared` | boolean | Whether the user is shared from a different Zendesk |
|
| ↳ `shared` | boolean | Whether the user is shared from a different Zendesk |
|
||||||
| ↳ `shared_agent` | boolean | Whether the agent is shared from a different Zendesk |
|
| ↳ `shared_agent` | boolean | Whether the agent is shared from a different Zendesk |
|
||||||
| ↳ `remote_photo_url` | string | URL to a remote photo |
|
| ↳ `remote_photo_url` | string | URL to a remote photo |
|
||||||
| `paging` | object | Pagination information |
|
| `paging` | object | Cursor-based pagination information |
|
||||||
|
| ↳ `after_cursor` | string | Cursor for fetching the next page of results |
|
||||||
|
| ↳ `has_more` | boolean | Whether more results are available |
|
||||||
| ↳ `next_page` | string | URL for next page of results |
|
| ↳ `next_page` | string | URL for next page of results |
|
||||||
| ↳ `previous_page` | string | URL for previous page of results |
|
|
||||||
| ↳ `count` | number | Total count of items |
|
|
||||||
| `metadata` | object | Response metadata |
|
| `metadata` | object | Response metadata |
|
||||||
| ↳ `total_returned` | number | Number of items returned in this response |
|
| ↳ `total_returned` | number | Number of items returned in this response |
|
||||||
| ↳ `has_more` | boolean | Whether more items are available |
|
| ↳ `has_more` | boolean | Whether more items are available |
|
||||||
@@ -999,7 +998,7 @@ Retrieve a list of organizations from Zendesk
|
|||||||
| `apiToken` | string | Yes | Zendesk API token |
|
| `apiToken` | string | Yes | Zendesk API token |
|
||||||
| `subdomain` | string | Yes | Your Zendesk subdomain \(e.g., "mycompany" for mycompany.zendesk.com\) |
|
| `subdomain` | string | Yes | Your Zendesk subdomain \(e.g., "mycompany" for mycompany.zendesk.com\) |
|
||||||
| `perPage` | string | No | Results per page as a number string \(default: "100", max: "100"\) |
|
| `perPage` | string | No | Results per page as a number string \(default: "100", max: "100"\) |
|
||||||
| `page` | string | No | Page number as a string \(e.g., "1", "2"\) |
|
| `pageAfter` | string | No | Cursor from a previous response to fetch the next page of results |
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|
||||||
@@ -1020,10 +1019,10 @@ Retrieve a list of organizations from Zendesk
|
|||||||
| ↳ `created_at` | string | When the organization was created \(ISO 8601 format\) |
|
| ↳ `created_at` | string | When the organization was created \(ISO 8601 format\) |
|
||||||
| ↳ `updated_at` | string | When the organization was last updated \(ISO 8601 format\) |
|
| ↳ `updated_at` | string | When the organization was last updated \(ISO 8601 format\) |
|
||||||
| ↳ `external_id` | string | External ID for linking to external records |
|
| ↳ `external_id` | string | External ID for linking to external records |
|
||||||
| `paging` | object | Pagination information |
|
| `paging` | object | Cursor-based pagination information |
|
||||||
|
| ↳ `after_cursor` | string | Cursor for fetching the next page of results |
|
||||||
|
| ↳ `has_more` | boolean | Whether more results are available |
|
||||||
| ↳ `next_page` | string | URL for next page of results |
|
| ↳ `next_page` | string | URL for next page of results |
|
||||||
| ↳ `previous_page` | string | URL for previous page of results |
|
|
||||||
| ↳ `count` | number | Total count of items |
|
|
||||||
| `metadata` | object | Response metadata |
|
| `metadata` | object | Response metadata |
|
||||||
| ↳ `total_returned` | number | Number of items returned in this response |
|
| ↳ `total_returned` | number | Number of items returned in this response |
|
||||||
| ↳ `has_more` | boolean | Whether more items are available |
|
| ↳ `has_more` | boolean | Whether more items are available |
|
||||||
@@ -1075,7 +1074,7 @@ Autocomplete organizations in Zendesk by name prefix (for name matching/autocomp
|
|||||||
| `subdomain` | string | Yes | Your Zendesk subdomain |
|
| `subdomain` | string | Yes | Your Zendesk subdomain |
|
||||||
| `name` | string | Yes | Organization name prefix to search for \(e.g., "Acme"\) |
|
| `name` | string | Yes | Organization name prefix to search for \(e.g., "Acme"\) |
|
||||||
| `perPage` | string | No | Results per page as a number string \(default: "100", max: "100"\) |
|
| `perPage` | string | No | Results per page as a number string \(default: "100", max: "100"\) |
|
||||||
| `page` | string | No | Page number as a string \(e.g., "1", "2"\) |
|
| `page` | string | No | Page number for pagination \(1-based\) |
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|
||||||
@@ -1096,10 +1095,10 @@ Autocomplete organizations in Zendesk by name prefix (for name matching/autocomp
|
|||||||
| ↳ `created_at` | string | When the organization was created \(ISO 8601 format\) |
|
| ↳ `created_at` | string | When the organization was created \(ISO 8601 format\) |
|
||||||
| ↳ `updated_at` | string | When the organization was last updated \(ISO 8601 format\) |
|
| ↳ `updated_at` | string | When the organization was last updated \(ISO 8601 format\) |
|
||||||
| ↳ `external_id` | string | External ID for linking to external records |
|
| ↳ `external_id` | string | External ID for linking to external records |
|
||||||
| `paging` | object | Pagination information |
|
| `paging` | object | Cursor-based pagination information |
|
||||||
|
| ↳ `after_cursor` | string | Cursor for fetching the next page of results |
|
||||||
|
| ↳ `has_more` | boolean | Whether more results are available |
|
||||||
| ↳ `next_page` | string | URL for next page of results |
|
| ↳ `next_page` | string | URL for next page of results |
|
||||||
| ↳ `previous_page` | string | URL for previous page of results |
|
|
||||||
| ↳ `count` | number | Total count of items |
|
|
||||||
| `metadata` | object | Response metadata |
|
| `metadata` | object | Response metadata |
|
||||||
| ↳ `total_returned` | number | Number of items returned in this response |
|
| ↳ `total_returned` | number | Number of items returned in this response |
|
||||||
| ↳ `has_more` | boolean | Whether more items are available |
|
| ↳ `has_more` | boolean | Whether more items are available |
|
||||||
@@ -1249,19 +1248,18 @@ Unified search across tickets, users, and organizations in Zendesk
|
|||||||
| `apiToken` | string | Yes | Zendesk API token |
|
| `apiToken` | string | Yes | Zendesk API token |
|
||||||
| `subdomain` | string | Yes | Your Zendesk subdomain |
|
| `subdomain` | string | Yes | Your Zendesk subdomain |
|
||||||
| `query` | string | Yes | Search query string using Zendesk search syntax \(e.g., "type:ticket status:open"\) |
|
| `query` | string | Yes | Search query string using Zendesk search syntax \(e.g., "type:ticket status:open"\) |
|
||||||
| `sortBy` | string | No | Sort field: "relevance", "created_at", "updated_at", "priority", "status", or "ticket_type" |
|
| `filterType` | string | Yes | Resource type to search for: "ticket", "user", "organization", or "group" |
|
||||||
| `sortOrder` | string | No | Sort order: "asc" or "desc" |
|
|
||||||
| `perPage` | string | No | Results per page as a number string \(default: "100", max: "100"\) |
|
| `perPage` | string | No | Results per page as a number string \(default: "100", max: "100"\) |
|
||||||
| `page` | string | No | Page number as a string \(e.g., "1", "2"\) |
|
| `pageAfter` | string | No | Cursor from a previous response to fetch the next page of results |
|
||||||
|
|
||||||
#### Output
|
#### Output
|
||||||
|
|
||||||
| Parameter | Type | Description |
|
| Parameter | Type | Description |
|
||||||
| --------- | ---- | ----------- |
|
| --------- | ---- | ----------- |
|
||||||
| `paging` | object | Pagination information |
|
| `paging` | object | Cursor-based pagination information |
|
||||||
|
| ↳ `after_cursor` | string | Cursor for fetching the next page of results |
|
||||||
|
| ↳ `has_more` | boolean | Whether more results are available |
|
||||||
| ↳ `next_page` | string | URL for next page of results |
|
| ↳ `next_page` | string | URL for next page of results |
|
||||||
| ↳ `previous_page` | string | URL for previous page of results |
|
|
||||||
| ↳ `count` | number | Total count of items |
|
|
||||||
| `metadata` | object | Response metadata |
|
| `metadata` | object | Response metadata |
|
||||||
| ↳ `total_returned` | number | Number of items returned in this response |
|
| ↳ `total_returned` | number | Number of items returned in this response |
|
||||||
| ↳ `has_more` | boolean | Whether more items are available |
|
| ↳ `has_more` | boolean | Whether more items are available |
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
'use server'
|
|
||||||
|
|
||||||
import { env } from '@/lib/core/config/env'
|
import { env } from '@/lib/core/config/env'
|
||||||
import { isProd } from '@/lib/core/config/feature-flags'
|
import { isProd } from '@/lib/core/config/feature-flags'
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ export const LandingNode = React.memo(function LandingNode({ data }: { data: Lan
|
|||||||
transform: isAnimated ? 'translateY(0) scale(1)' : 'translateY(8px) scale(0.98)',
|
transform: isAnimated ? 'translateY(0) scale(1)' : 'translateY(8px) scale(0.98)',
|
||||||
transition:
|
transition:
|
||||||
'opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1), transform 0.6s cubic-bezier(0.22, 1, 0.36, 1)',
|
'opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1), transform 0.6s cubic-bezier(0.22, 1, 0.36, 1)',
|
||||||
willChange: 'transform, opacity',
|
willChange: isAnimated ? 'auto' : 'transform, opacity',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<LandingBlock icon={data.icon} color={data.color} name={data.name} tags={data.tags} />
|
<LandingBlock icon={data.icon} color={data.color} name={data.name} tags={data.tags} />
|
||||||
|
|||||||
@@ -67,7 +67,6 @@ export const LandingEdge = React.memo(function LandingEdge(props: EdgeProps) {
|
|||||||
strokeLinejoin: 'round',
|
strokeLinejoin: 'round',
|
||||||
pointerEvents: 'none',
|
pointerEvents: 'none',
|
||||||
animation: `landing-edge-dash-${id} 1s linear infinite`,
|
animation: `landing-edge-dash-${id} 1s linear infinite`,
|
||||||
willChange: 'stroke-dashoffset',
|
|
||||||
...style,
|
...style,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -754,3 +754,100 @@ input[type="search"]::-ms-clear {
|
|||||||
text-decoration: none !important;
|
text-decoration: none !important;
|
||||||
color: inherit !important;
|
color: inherit !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Respect user's prefers-reduced-motion setting (WCAG 2.3.3)
|
||||||
|
* Disables animations and transitions for users who prefer reduced motion.
|
||||||
|
*/
|
||||||
|
@media (prefers-reduced-motion: reduce) {
|
||||||
|
*,
|
||||||
|
*::before,
|
||||||
|
*::after {
|
||||||
|
animation-duration: 0.01ms !important;
|
||||||
|
animation-iteration-count: 1 !important;
|
||||||
|
transition-duration: 0.01ms !important;
|
||||||
|
scroll-behavior: auto !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* WandPromptBar status indicator */
|
||||||
|
@keyframes smoke-pulse {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: scale(0.8);
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.1);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-indicator {
|
||||||
|
position: relative;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: hsl(var(--muted-foreground) / 0.5);
|
||||||
|
transition: background-color 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-indicator.streaming {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-indicator.streaming::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
border-radius: 50%;
|
||||||
|
background: radial-gradient(
|
||||||
|
circle,
|
||||||
|
hsl(var(--primary) / 0.9) 0%,
|
||||||
|
hsl(var(--primary) / 0.4) 60%,
|
||||||
|
transparent 80%
|
||||||
|
);
|
||||||
|
animation: smoke-pulse 1.8s ease-in-out infinite;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .status-indicator.streaming::before {
|
||||||
|
background: #6b7280;
|
||||||
|
opacity: 0.9;
|
||||||
|
animation: smoke-pulse 1.8s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MessageContainer loading dot */
|
||||||
|
@keyframes growShrink {
|
||||||
|
0%,
|
||||||
|
100% {
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-dot {
|
||||||
|
animation: growShrink 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Subflow node z-index and drag-over styles */
|
||||||
|
.workflow-container .react-flow__node-subflowNode {
|
||||||
|
z-index: -1 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.workflow-container .react-flow__node-subflowNode:has([data-subflow-selected="true"]) {
|
||||||
|
z-index: 10 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loop-node-drag-over,
|
||||||
|
.parallel-node-drag-over {
|
||||||
|
box-shadow: 0 0 0 1.75px var(--brand-secondary) !important;
|
||||||
|
border-radius: 8px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.react-flow__node[data-parent-node-id] .react-flow__handle {
|
||||||
|
z-index: 30;
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,15 +22,20 @@ interface PipedriveFile {
|
|||||||
interface PipedriveApiResponse {
|
interface PipedriveApiResponse {
|
||||||
success: boolean
|
success: boolean
|
||||||
data?: PipedriveFile[]
|
data?: PipedriveFile[]
|
||||||
|
additional_data?: {
|
||||||
|
pagination?: {
|
||||||
|
more_items_in_collection: boolean
|
||||||
|
next_start: number
|
||||||
|
}
|
||||||
|
}
|
||||||
error?: string
|
error?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const PipedriveGetFilesSchema = z.object({
|
const PipedriveGetFilesSchema = z.object({
|
||||||
accessToken: z.string().min(1, 'Access token is required'),
|
accessToken: z.string().min(1, 'Access token is required'),
|
||||||
deal_id: z.string().optional().nullable(),
|
sort: z.enum(['id', 'update_time']).optional().nullable(),
|
||||||
person_id: z.string().optional().nullable(),
|
|
||||||
org_id: z.string().optional().nullable(),
|
|
||||||
limit: z.string().optional().nullable(),
|
limit: z.string().optional().nullable(),
|
||||||
|
start: z.string().optional().nullable(),
|
||||||
downloadFiles: z.boolean().optional().default(false),
|
downloadFiles: z.boolean().optional().default(false),
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -54,20 +59,19 @@ export async function POST(request: NextRequest) {
|
|||||||
const body = await request.json()
|
const body = await request.json()
|
||||||
const validatedData = PipedriveGetFilesSchema.parse(body)
|
const validatedData = PipedriveGetFilesSchema.parse(body)
|
||||||
|
|
||||||
const { accessToken, deal_id, person_id, org_id, limit, downloadFiles } = validatedData
|
const { accessToken, sort, limit, start, downloadFiles } = validatedData
|
||||||
|
|
||||||
const baseUrl = 'https://api.pipedrive.com/v1/files'
|
const baseUrl = 'https://api.pipedrive.com/v1/files'
|
||||||
const queryParams = new URLSearchParams()
|
const queryParams = new URLSearchParams()
|
||||||
|
|
||||||
if (deal_id) queryParams.append('deal_id', deal_id)
|
if (sort) queryParams.append('sort', sort)
|
||||||
if (person_id) queryParams.append('person_id', person_id)
|
|
||||||
if (org_id) queryParams.append('org_id', org_id)
|
|
||||||
if (limit) queryParams.append('limit', limit)
|
if (limit) queryParams.append('limit', limit)
|
||||||
|
if (start) queryParams.append('start', start)
|
||||||
|
|
||||||
const queryString = queryParams.toString()
|
const queryString = queryParams.toString()
|
||||||
const apiUrl = queryString ? `${baseUrl}?${queryString}` : baseUrl
|
const apiUrl = queryString ? `${baseUrl}?${queryString}` : baseUrl
|
||||||
|
|
||||||
logger.info(`[${requestId}] Fetching files from Pipedrive`, { deal_id, person_id, org_id })
|
logger.info(`[${requestId}] Fetching files from Pipedrive`)
|
||||||
|
|
||||||
const urlValidation = await validateUrlWithDNS(apiUrl, 'apiUrl')
|
const urlValidation = await validateUrlWithDNS(apiUrl, 'apiUrl')
|
||||||
if (!urlValidation.isValid) {
|
if (!urlValidation.isValid) {
|
||||||
@@ -93,6 +97,8 @@ export async function POST(request: NextRequest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const files = data.data || []
|
const files = data.data || []
|
||||||
|
const hasMore = data.additional_data?.pagination?.more_items_in_collection || false
|
||||||
|
const nextStart = data.additional_data?.pagination?.next_start ?? null
|
||||||
const downloadedFiles: Array<{
|
const downloadedFiles: Array<{
|
||||||
name: string
|
name: string
|
||||||
mimeType: string
|
mimeType: string
|
||||||
@@ -149,6 +155,8 @@ export async function POST(request: NextRequest) {
|
|||||||
files,
|
files,
|
||||||
downloadedFiles: downloadedFiles.length > 0 ? downloadedFiles : undefined,
|
downloadedFiles: downloadedFiles.length > 0 ? downloadedFiles : undefined,
|
||||||
total_items: files.length,
|
total_items: files.length,
|
||||||
|
has_more: hasMore,
|
||||||
|
next_start: nextStart,
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -30,21 +30,6 @@ export const ChatMessageContainer = memo(function ChatMessageContainer({
|
|||||||
}: ChatMessageContainerProps) {
|
}: ChatMessageContainerProps) {
|
||||||
return (
|
return (
|
||||||
<div className='relative flex flex-1 flex-col overflow-hidden bg-white'>
|
<div className='relative flex flex-1 flex-col overflow-hidden bg-white'>
|
||||||
<style jsx>{`
|
|
||||||
@keyframes growShrink {
|
|
||||||
0%,
|
|
||||||
100% {
|
|
||||||
transform: scale(0.9);
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: scale(1.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.loading-dot {
|
|
||||||
animation: growShrink 1.5s infinite ease-in-out;
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
|
|
||||||
{/* Scrollable Messages Area */}
|
{/* Scrollable Messages Area */}
|
||||||
<div
|
<div
|
||||||
ref={messagesContainerRef}
|
ref={messagesContainerRef}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ export function VoiceInterface({
|
|||||||
const [state, setState] = useState<'idle' | 'listening' | 'agent_speaking'>('idle')
|
const [state, setState] = useState<'idle' | 'listening' | 'agent_speaking'>('idle')
|
||||||
const [isInitialized, setIsInitialized] = useState(false)
|
const [isInitialized, setIsInitialized] = useState(false)
|
||||||
const [isMuted, setIsMuted] = useState(false)
|
const [isMuted, setIsMuted] = useState(false)
|
||||||
const [audioLevels, setAudioLevels] = useState<number[]>(new Array(200).fill(0))
|
const [audioLevels, setAudioLevels] = useState<number[]>(() => new Array(200).fill(0))
|
||||||
const [permissionStatus, setPermissionStatus] = useState<'prompt' | 'granted' | 'denied'>(
|
const [permissionStatus, setPermissionStatus] = useState<'prompt' | 'granted' | 'denied'>(
|
||||||
'prompt'
|
'prompt'
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { redirect } from 'next/navigation'
|
import { redirect, unstable_rethrow } from 'next/navigation'
|
||||||
import { getSession } from '@/lib/auth'
|
import { getSession } from '@/lib/auth'
|
||||||
import { getWorkspaceFile } from '@/lib/uploads/contexts/workspace'
|
import { getWorkspaceFile } from '@/lib/uploads/contexts/workspace'
|
||||||
import { verifyWorkspaceMembership } from '@/app/api/workflows/utils'
|
import { verifyWorkspaceMembership } from '@/app/api/workflows/utils'
|
||||||
@@ -14,7 +14,6 @@ interface FileViewerPageProps {
|
|||||||
export default async function FileViewerPage({ params }: FileViewerPageProps) {
|
export default async function FileViewerPage({ params }: FileViewerPageProps) {
|
||||||
const { workspaceId, fileId } = await params
|
const { workspaceId, fileId } = await params
|
||||||
|
|
||||||
try {
|
|
||||||
const session = await getSession()
|
const session = await getSession()
|
||||||
if (!session?.user?.id) {
|
if (!session?.user?.id) {
|
||||||
redirect('/')
|
redirect('/')
|
||||||
@@ -25,13 +24,17 @@ export default async function FileViewerPage({ params }: FileViewerPageProps) {
|
|||||||
redirect(`/workspace/${workspaceId}`)
|
redirect(`/workspace/${workspaceId}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileRecord = await getWorkspaceFile(workspaceId, fileId)
|
let fileRecord: Awaited<ReturnType<typeof getWorkspaceFile>>
|
||||||
|
try {
|
||||||
|
fileRecord = await getWorkspaceFile(workspaceId, fileId)
|
||||||
|
} catch (error) {
|
||||||
|
unstable_rethrow(error)
|
||||||
|
redirect(`/workspace/${workspaceId}`)
|
||||||
|
}
|
||||||
|
|
||||||
if (!fileRecord) {
|
if (!fileRecord) {
|
||||||
redirect(`/workspace/${workspaceId}`)
|
redirect(`/workspace/${workspaceId}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
return <FileViewer file={fileRecord} />
|
return <FileViewer file={fileRecord} />
|
||||||
} catch (error) {
|
|
||||||
redirect(`/workspace/${workspaceId}`)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,10 +131,8 @@ export const Copilot = forwardRef<CopilotRef, CopilotProps>(({ panelWidth }, ref
|
|||||||
resumeActiveStream,
|
resumeActiveStream,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Handle scroll management (80px stickiness for copilot)
|
// Handle scroll management
|
||||||
const { scrollAreaRef, scrollToBottom } = useScrollManagement(messages, isSendingMessage, {
|
const { scrollAreaRef, scrollToBottom } = useScrollManagement(messages, isSendingMessage)
|
||||||
stickinessThreshold: 40,
|
|
||||||
})
|
|
||||||
|
|
||||||
// Handle chat history grouping
|
// Handle chat history grouping
|
||||||
const { groupedChats, handleHistoryDropdownOpen: handleHistoryDropdownOpenHook } = useChatHistory(
|
const { groupedChats, handleHistoryDropdownOpen: handleHistoryDropdownOpenHook } = useChatHistory(
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import { isEqual } from 'lodash'
|
import isEqual from 'lodash/isEqual'
|
||||||
import { useReactFlow } from 'reactflow'
|
import { useReactFlow } from 'reactflow'
|
||||||
import { useStoreWithEqualityFn } from 'zustand/traditional'
|
import { useStoreWithEqualityFn } from 'zustand/traditional'
|
||||||
import { Combobox, type ComboboxOption } from '@/components/emcn/components'
|
import { Combobox, type ComboboxOption } from '@/components/emcn/components'
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import { isEqual } from 'lodash'
|
import isEqual from 'lodash/isEqual'
|
||||||
import { useStoreWithEqualityFn } from 'zustand/traditional'
|
import { useStoreWithEqualityFn } from 'zustand/traditional'
|
||||||
import { Badge } from '@/components/emcn'
|
import { Badge } from '@/components/emcn'
|
||||||
import { Combobox, type ComboboxOption } from '@/components/emcn/components'
|
import { Combobox, type ComboboxOption } from '@/components/emcn/components'
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
} from 'react'
|
} from 'react'
|
||||||
import { isEqual } from 'lodash'
|
import isEqual from 'lodash/isEqual'
|
||||||
import { ChevronDown, ChevronsUpDown, ChevronUp, Plus } from 'lucide-react'
|
import { ChevronDown, ChevronsUpDown, ChevronUp, Plus } from 'lucide-react'
|
||||||
import { Button, Popover, PopoverContent, PopoverItem, PopoverTrigger } from '@/components/emcn'
|
import { Button, Popover, PopoverContent, PopoverItem, PopoverTrigger } from '@/components/emcn'
|
||||||
import { Trash } from '@/components/emcn/icons/trash'
|
import { Trash } from '@/components/emcn/icons/trash'
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { type JSX, type MouseEvent, memo, useCallback, useRef, useState } from 'react'
|
import { type JSX, type MouseEvent, memo, useCallback, useRef, useState } from 'react'
|
||||||
import { isEqual } from 'lodash'
|
import isEqual from 'lodash/isEqual'
|
||||||
import { AlertTriangle, ArrowLeftRight, ArrowUp, Check, Clipboard } from 'lucide-react'
|
import { AlertTriangle, ArrowLeftRight, ArrowUp, Check, Clipboard } from 'lucide-react'
|
||||||
import { Button, Input, Label, Tooltip } from '@/components/emcn/components'
|
import { Button, Input, Label, Tooltip } from '@/components/emcn/components'
|
||||||
import { cn } from '@/lib/core/utils/cn'
|
import { cn } from '@/lib/core/utils/cn'
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
import { isEqual } from 'lodash'
|
import isEqual from 'lodash/isEqual'
|
||||||
import {
|
import {
|
||||||
BookOpen,
|
BookOpen,
|
||||||
Check,
|
Check,
|
||||||
|
|||||||
@@ -10,40 +10,6 @@ import { ActionBar } from '@/app/workspace/[workspaceId]/w/[workflowId]/componen
|
|||||||
import { useCurrentWorkflow } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks'
|
import { useCurrentWorkflow } from '@/app/workspace/[workspaceId]/w/[workflowId]/hooks'
|
||||||
import { usePanelEditorStore } from '@/stores/panel'
|
import { usePanelEditorStore } from '@/stores/panel'
|
||||||
|
|
||||||
/**
|
|
||||||
* Global styles for subflow nodes (loop and parallel containers).
|
|
||||||
* Includes animations for drag-over states and hover effects.
|
|
||||||
*
|
|
||||||
* @returns Style component with global CSS
|
|
||||||
*/
|
|
||||||
const SubflowNodeStyles: React.FC = () => {
|
|
||||||
return (
|
|
||||||
<style jsx global>{`
|
|
||||||
/* Z-index management for subflow nodes - default behind blocks */
|
|
||||||
.workflow-container .react-flow__node-subflowNode {
|
|
||||||
z-index: -1 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Selected subflows appear above other subflows but below blocks (z-21) */
|
|
||||||
.workflow-container .react-flow__node-subflowNode:has([data-subflow-selected='true']) {
|
|
||||||
z-index: 10 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Drag-over states */
|
|
||||||
.loop-node-drag-over,
|
|
||||||
.parallel-node-drag-over {
|
|
||||||
box-shadow: 0 0 0 1.75px var(--brand-secondary) !important;
|
|
||||||
border-radius: 8px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle z-index for nested nodes */
|
|
||||||
.react-flow__node[data-parent-node-id] .react-flow__handle {
|
|
||||||
z-index: 30;
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data structure for subflow nodes (loop and parallel containers)
|
* Data structure for subflow nodes (loop and parallel containers)
|
||||||
*/
|
*/
|
||||||
@@ -151,8 +117,6 @@ export const SubflowNodeComponent = memo(({ data, id, selected }: NodeProps<Subf
|
|||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<SubflowNodeStyles />
|
|
||||||
<div className='group relative'>
|
<div className='group relative'>
|
||||||
<div
|
<div
|
||||||
ref={blockRef}
|
ref={blockRef}
|
||||||
@@ -277,7 +241,6 @@ export const SubflowNodeComponent = memo(({ data, id, selected }: NodeProps<Subf
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -134,57 +134,6 @@ export function WandPromptBar({
|
|||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style jsx global>{`
|
|
||||||
|
|
||||||
@keyframes smoke-pulse {
|
|
||||||
0%,
|
|
||||||
100% {
|
|
||||||
transform: scale(0.8);
|
|
||||||
opacity: 0.4;
|
|
||||||
}
|
|
||||||
50% {
|
|
||||||
transform: scale(1.1);
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-indicator {
|
|
||||||
position: relative;
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
border-radius: 50%;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: hsl(var(--muted-foreground) / 0.5);
|
|
||||||
transition: background-color 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-indicator.streaming {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-indicator.streaming::before {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: radial-gradient(
|
|
||||||
circle,
|
|
||||||
hsl(var(--primary) / 0.9) 0%,
|
|
||||||
hsl(var(--primary) / 0.4) 60%,
|
|
||||||
transparent 80%
|
|
||||||
);
|
|
||||||
animation: smoke-pulse 1.8s ease-in-out infinite;
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dark .status-indicator.streaming::before {
|
|
||||||
background: #6b7280;
|
|
||||||
opacity: 0.9;
|
|
||||||
animation: smoke-pulse 1.8s ease-in-out infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
`}</style>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { memo, useCallback, useEffect, useMemo, useRef } from 'react'
|
import { memo, useCallback, useEffect, useMemo, useRef } from 'react'
|
||||||
import { createLogger } from '@sim/logger'
|
import { createLogger } from '@sim/logger'
|
||||||
import { isEqual } from 'lodash'
|
import isEqual from 'lodash/isEqual'
|
||||||
import { useParams } from 'next/navigation'
|
import { useParams } from 'next/navigation'
|
||||||
import { Handle, type NodeProps, Position, useUpdateNodeInternals } from 'reactflow'
|
import { Handle, type NodeProps, Position, useUpdateNodeInternals } from 'reactflow'
|
||||||
import { useStoreWithEqualityFn } from 'zustand/traditional'
|
import { useStoreWithEqualityFn } from 'zustand/traditional'
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ interface UseScrollManagementOptions {
|
|||||||
/**
|
/**
|
||||||
* Distance from bottom (in pixels) within which auto-scroll stays active
|
* Distance from bottom (in pixels) within which auto-scroll stays active
|
||||||
* @remarks Lower values = less sticky (user can scroll away easier)
|
* @remarks Lower values = less sticky (user can scroll away easier)
|
||||||
* @defaultValue 100
|
* @defaultValue 30
|
||||||
*/
|
*/
|
||||||
stickinessThreshold?: number
|
stickinessThreshold?: number
|
||||||
}
|
}
|
||||||
@@ -41,7 +41,7 @@ export function useScrollManagement(
|
|||||||
const lastScrollTopRef = useRef(0)
|
const lastScrollTopRef = useRef(0)
|
||||||
|
|
||||||
const scrollBehavior = options?.behavior ?? 'smooth'
|
const scrollBehavior = options?.behavior ?? 'smooth'
|
||||||
const stickinessThreshold = options?.stickinessThreshold ?? 100
|
const stickinessThreshold = options?.stickinessThreshold ?? 30
|
||||||
|
|
||||||
/** Scrolls the container to the bottom */
|
/** Scrolls the container to the bottom */
|
||||||
const scrollToBottom = useCallback(() => {
|
const scrollToBottom = useCallback(() => {
|
||||||
|
|||||||
@@ -514,6 +514,7 @@ export function HelpModal({ open, onOpenChange, workflowId, workspaceId }: HelpM
|
|||||||
alt={`Preview ${index + 1}`}
|
alt={`Preview ${index + 1}`}
|
||||||
fill
|
fill
|
||||||
unoptimized
|
unoptimized
|
||||||
|
sizes='(max-width: 768px) 100vw, 50vw'
|
||||||
className='object-contain'
|
className='object-contain'
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -165,12 +165,16 @@ export function CancelSubscription({ subscription, subscriptionData }: CancelSub
|
|||||||
logger.info('Subscription restored successfully', result)
|
logger.info('Subscription restored successfully', result)
|
||||||
}
|
}
|
||||||
|
|
||||||
await queryClient.invalidateQueries({ queryKey: subscriptionKeys.all })
|
await Promise.all([
|
||||||
if (activeOrgId) {
|
queryClient.invalidateQueries({ queryKey: subscriptionKeys.all }),
|
||||||
await queryClient.invalidateQueries({ queryKey: organizationKeys.detail(activeOrgId) })
|
...(activeOrgId
|
||||||
await queryClient.invalidateQueries({ queryKey: organizationKeys.billing(activeOrgId) })
|
? [
|
||||||
await queryClient.invalidateQueries({ queryKey: organizationKeys.lists() })
|
queryClient.invalidateQueries({ queryKey: organizationKeys.detail(activeOrgId) }),
|
||||||
}
|
queryClient.invalidateQueries({ queryKey: organizationKeys.billing(activeOrgId) }),
|
||||||
|
queryClient.invalidateQueries({ queryKey: organizationKeys.lists() }),
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
])
|
||||||
|
|
||||||
setIsDialogOpen(false)
|
setIsDialogOpen(false)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export const UsageLimit = forwardRef<UsageLimitRef, UsageLimitProps>(
|
|||||||
},
|
},
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
const [inputValue, setInputValue] = useState(currentLimit.toString())
|
const [inputValue, setInputValue] = useState(() => currentLimit.toString())
|
||||||
const [hasError, setHasError] = useState(false)
|
const [hasError, setHasError] = useState(false)
|
||||||
const [errorType, setErrorType] = useState<'general' | 'belowUsage' | null>(null)
|
const [errorType, setErrorType] = useState<'general' | 'belowUsage' | null>(null)
|
||||||
const [isEditing, setIsEditing] = useState(false)
|
const [isEditing, setIsEditing] = useState(false)
|
||||||
|
|||||||
@@ -92,12 +92,9 @@ export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
|
|||||||
field: 'operation',
|
field: 'operation',
|
||||||
value: [
|
value: [
|
||||||
'incidentio_incidents_list',
|
'incidentio_incidents_list',
|
||||||
'incidentio_actions_list',
|
|
||||||
'incidentio_follow_ups_list',
|
|
||||||
'incidentio_users_list',
|
'incidentio_users_list',
|
||||||
'incidentio_workflows_list',
|
'incidentio_workflows_list',
|
||||||
'incidentio_schedules_list',
|
'incidentio_schedules_list',
|
||||||
'incidentio_escalations_list',
|
|
||||||
'incidentio_incident_updates_list',
|
'incidentio_incident_updates_list',
|
||||||
'incidentio_schedule_entries_list',
|
'incidentio_schedule_entries_list',
|
||||||
],
|
],
|
||||||
@@ -113,6 +110,7 @@ export const IncidentioBlock: BlockConfig<IncidentioResponse> = {
|
|||||||
field: 'operation',
|
field: 'operation',
|
||||||
value: [
|
value: [
|
||||||
'incidentio_incidents_list',
|
'incidentio_incidents_list',
|
||||||
|
'incidentio_users_list',
|
||||||
'incidentio_workflows_list',
|
'incidentio_workflows_list',
|
||||||
'incidentio_schedules_list',
|
'incidentio_schedules_list',
|
||||||
'incidentio_incident_updates_list',
|
'incidentio_incident_updates_list',
|
||||||
|
|||||||
@@ -216,31 +216,21 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
|
|||||||
condition: { field: 'operation', value: ['update_deal'] },
|
condition: { field: 'operation', value: ['update_deal'] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'deal_id',
|
id: 'sort',
|
||||||
title: 'Deal ID',
|
title: 'Sort By',
|
||||||
type: 'short-input',
|
type: 'dropdown',
|
||||||
placeholder: 'Filter by deal ID ',
|
options: [
|
||||||
condition: { field: 'operation', value: ['get_files'] },
|
{ label: 'ID', id: 'id' },
|
||||||
},
|
{ label: 'Update Time', id: 'update_time' },
|
||||||
{
|
],
|
||||||
id: 'person_id',
|
value: () => 'id',
|
||||||
title: 'Person ID',
|
|
||||||
type: 'short-input',
|
|
||||||
placeholder: 'Filter by person ID ',
|
|
||||||
condition: { field: 'operation', value: ['get_files'] },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'org_id',
|
|
||||||
title: 'Organization ID',
|
|
||||||
type: 'short-input',
|
|
||||||
placeholder: 'Filter by organization ID ',
|
|
||||||
condition: { field: 'operation', value: ['get_files'] },
|
condition: { field: 'operation', value: ['get_files'] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'limit',
|
id: 'limit',
|
||||||
title: 'Limit',
|
title: 'Limit',
|
||||||
type: 'short-input',
|
type: 'short-input',
|
||||||
placeholder: 'Number of results (default 100, max 500)',
|
placeholder: 'Number of results (default 100, max 100)',
|
||||||
condition: { field: 'operation', value: ['get_files'] },
|
condition: { field: 'operation', value: ['get_files'] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -305,8 +295,28 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
|
|||||||
id: 'cursor',
|
id: 'cursor',
|
||||||
title: 'Cursor',
|
title: 'Cursor',
|
||||||
type: 'short-input',
|
type: 'short-input',
|
||||||
placeholder: 'Pagination cursor (optional)',
|
placeholder: 'Pagination cursor from previous response',
|
||||||
condition: { field: 'operation', value: ['get_pipelines'] },
|
condition: {
|
||||||
|
field: 'operation',
|
||||||
|
value: ['get_all_deals', 'get_projects'],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'start',
|
||||||
|
title: 'Start (Offset)',
|
||||||
|
type: 'short-input',
|
||||||
|
placeholder: 'Pagination offset (e.g., 0, 100, 200)',
|
||||||
|
condition: {
|
||||||
|
field: 'operation',
|
||||||
|
value: [
|
||||||
|
'get_activities',
|
||||||
|
'get_leads',
|
||||||
|
'get_files',
|
||||||
|
'get_pipeline_deals',
|
||||||
|
'get_mail_messages',
|
||||||
|
'get_pipelines',
|
||||||
|
],
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'pipeline_id',
|
id: 'pipeline_id',
|
||||||
@@ -323,19 +333,6 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
|
|||||||
placeholder: 'Filter by stage ID ',
|
placeholder: 'Filter by stage ID ',
|
||||||
condition: { field: 'operation', value: ['get_pipeline_deals'] },
|
condition: { field: 'operation', value: ['get_pipeline_deals'] },
|
||||||
},
|
},
|
||||||
{
|
|
||||||
id: 'status',
|
|
||||||
title: 'Status',
|
|
||||||
type: 'dropdown',
|
|
||||||
options: [
|
|
||||||
{ label: 'All', id: '' },
|
|
||||||
{ label: 'Open', id: 'open' },
|
|
||||||
{ label: 'Won', id: 'won' },
|
|
||||||
{ label: 'Lost', id: 'lost' },
|
|
||||||
],
|
|
||||||
value: () => '',
|
|
||||||
condition: { field: 'operation', value: ['get_pipeline_deals'] },
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
id: 'limit',
|
id: 'limit',
|
||||||
title: 'Limit',
|
title: 'Limit',
|
||||||
@@ -426,22 +423,29 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
|
|||||||
id: 'deal_id',
|
id: 'deal_id',
|
||||||
title: 'Deal ID',
|
title: 'Deal ID',
|
||||||
type: 'short-input',
|
type: 'short-input',
|
||||||
placeholder: 'Filter by deal ID ',
|
placeholder: 'Associated deal ID ',
|
||||||
condition: { field: 'operation', value: ['get_activities', 'create_activity'] },
|
condition: { field: 'operation', value: ['create_activity'] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'person_id',
|
id: 'person_id',
|
||||||
title: 'Person ID',
|
title: 'Person ID',
|
||||||
type: 'short-input',
|
type: 'short-input',
|
||||||
placeholder: 'Filter by person ID ',
|
placeholder: 'Associated person ID ',
|
||||||
condition: { field: 'operation', value: ['get_activities', 'create_activity'] },
|
condition: { field: 'operation', value: ['create_activity'] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'org_id',
|
id: 'org_id',
|
||||||
title: 'Organization ID',
|
title: 'Organization ID',
|
||||||
type: 'short-input',
|
type: 'short-input',
|
||||||
placeholder: 'Filter by organization ID ',
|
placeholder: 'Associated organization ID ',
|
||||||
condition: { field: 'operation', value: ['get_activities', 'create_activity'] },
|
condition: { field: 'operation', value: ['create_activity'] },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'user_id',
|
||||||
|
title: 'User ID',
|
||||||
|
type: 'short-input',
|
||||||
|
placeholder: 'Filter by user ID',
|
||||||
|
condition: { field: 'operation', value: ['get_activities'] },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'type',
|
id: 'type',
|
||||||
@@ -781,7 +785,8 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
|
|||||||
thread_id: { type: 'string', description: 'Mail thread ID' },
|
thread_id: { type: 'string', description: 'Mail thread ID' },
|
||||||
sort_by: { type: 'string', description: 'Field to sort by' },
|
sort_by: { type: 'string', description: 'Field to sort by' },
|
||||||
sort_direction: { type: 'string', description: 'Sorting direction' },
|
sort_direction: { type: 'string', description: 'Sorting direction' },
|
||||||
cursor: { type: 'string', description: 'Pagination cursor' },
|
cursor: { type: 'string', description: 'Pagination cursor (v2 endpoints)' },
|
||||||
|
start: { type: 'string', description: 'Pagination start offset (v1 endpoints)' },
|
||||||
project_id: { type: 'string', description: 'Project ID' },
|
project_id: { type: 'string', description: 'Project ID' },
|
||||||
description: { type: 'string', description: 'Description' },
|
description: { type: 'string', description: 'Description' },
|
||||||
start_date: { type: 'string', description: 'Start date' },
|
start_date: { type: 'string', description: 'Start date' },
|
||||||
@@ -793,12 +798,15 @@ Return ONLY the date string in YYYY-MM-DD format - no explanations, no quotes, n
|
|||||||
due_time: { type: 'string', description: 'Due time' },
|
due_time: { type: 'string', description: 'Due time' },
|
||||||
duration: { type: 'string', description: 'Duration' },
|
duration: { type: 'string', description: 'Duration' },
|
||||||
done: { type: 'string', description: 'Completion status' },
|
done: { type: 'string', description: 'Completion status' },
|
||||||
|
user_id: { type: 'string', description: 'User ID' },
|
||||||
note: { type: 'string', description: 'Notes' },
|
note: { type: 'string', description: 'Notes' },
|
||||||
lead_id: { type: 'string', description: 'Lead ID' },
|
lead_id: { type: 'string', description: 'Lead ID' },
|
||||||
archived: { type: 'string', description: 'Archived status' },
|
archived: { type: 'string', description: 'Archived status' },
|
||||||
value_amount: { type: 'string', description: 'Value amount' },
|
value_amount: { type: 'string', description: 'Value amount' },
|
||||||
value_currency: { type: 'string', description: 'Value currency' },
|
value_currency: { type: 'string', description: 'Value currency' },
|
||||||
is_archived: { type: 'string', description: 'Archive status' },
|
is_archived: { type: 'string', description: 'Archive status' },
|
||||||
|
organization_id: { type: 'string', description: 'Organization ID' },
|
||||||
|
owner_id: { type: 'string', description: 'Owner user ID' },
|
||||||
},
|
},
|
||||||
outputs: {
|
outputs: {
|
||||||
deals: { type: 'json', description: 'Array of deal objects' },
|
deals: { type: 'json', description: 'Array of deal objects' },
|
||||||
|
|||||||
@@ -445,6 +445,13 @@ Return ONLY the order by expression - no explanations, no extra text.`,
|
|||||||
placeholder: '100',
|
placeholder: '100',
|
||||||
condition: { field: 'operation', value: 'query' },
|
condition: { field: 'operation', value: 'query' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'offset',
|
||||||
|
title: 'Offset',
|
||||||
|
type: 'short-input',
|
||||||
|
placeholder: '0',
|
||||||
|
condition: { field: 'operation', value: 'query' },
|
||||||
|
},
|
||||||
// Vector search operation fields
|
// Vector search operation fields
|
||||||
{
|
{
|
||||||
id: 'functionName',
|
id: 'functionName',
|
||||||
@@ -543,6 +550,13 @@ Return ONLY the order by expression - no explanations, no extra text.`,
|
|||||||
placeholder: '100',
|
placeholder: '100',
|
||||||
condition: { field: 'operation', value: 'text_search' },
|
condition: { field: 'operation', value: 'text_search' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'offset',
|
||||||
|
title: 'Offset',
|
||||||
|
type: 'short-input',
|
||||||
|
placeholder: '0',
|
||||||
|
condition: { field: 'operation', value: 'text_search' },
|
||||||
|
},
|
||||||
// Count operation fields
|
// Count operation fields
|
||||||
{
|
{
|
||||||
id: 'filter',
|
id: 'filter',
|
||||||
|
|||||||
@@ -66,6 +66,20 @@ export const TypeformBlock: BlockConfig<TypeformResponse> = {
|
|||||||
placeholder: 'Number of responses per page (default: 25)',
|
placeholder: 'Number of responses per page (default: 25)',
|
||||||
condition: { field: 'operation', value: 'typeform_responses' },
|
condition: { field: 'operation', value: 'typeform_responses' },
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'before',
|
||||||
|
title: 'Before (Cursor)',
|
||||||
|
type: 'short-input',
|
||||||
|
placeholder: 'Cursor token from previous response for pagination',
|
||||||
|
condition: { field: 'operation', value: 'typeform_responses' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'after',
|
||||||
|
title: 'After (Cursor)',
|
||||||
|
type: 'short-input',
|
||||||
|
placeholder: 'Cursor token from previous response for newer results',
|
||||||
|
condition: { field: 'operation', value: 'typeform_responses' },
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'since',
|
id: 'since',
|
||||||
title: 'Since',
|
title: 'Since',
|
||||||
@@ -380,6 +394,8 @@ Do not include any explanations, markdown formatting, or other text outside the
|
|||||||
apiKey: { type: 'string', description: 'Personal access token' },
|
apiKey: { type: 'string', description: 'Personal access token' },
|
||||||
// Response operation params
|
// Response operation params
|
||||||
pageSize: { type: 'number', description: 'Responses per page' },
|
pageSize: { type: 'number', description: 'Responses per page' },
|
||||||
|
before: { type: 'string', description: 'Cursor token for fetching the next page' },
|
||||||
|
after: { type: 'string', description: 'Cursor token for fetching newer results' },
|
||||||
since: { type: 'string', description: 'Start date filter' },
|
since: { type: 'string', description: 'Start date filter' },
|
||||||
until: { type: 'string', description: 'End date filter' },
|
until: { type: 'string', description: 'End date filter' },
|
||||||
completed: { type: 'string', description: 'Completion status filter' },
|
completed: { type: 'string', description: 'Completion status filter' },
|
||||||
|
|||||||
@@ -444,33 +444,36 @@ Return ONLY the search query - no explanations.`,
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'sortBy',
|
id: 'filterType',
|
||||||
title: 'Sort By',
|
title: 'Resource Type',
|
||||||
type: 'dropdown',
|
type: 'dropdown',
|
||||||
options: [
|
options: [
|
||||||
{ label: 'Relevance', id: 'relevance' },
|
{ label: 'Ticket', id: 'ticket' },
|
||||||
{ label: 'Created At', id: 'created_at' },
|
{ label: 'User', id: 'user' },
|
||||||
{ label: 'Updated At', id: 'updated_at' },
|
{ label: 'Organization', id: 'organization' },
|
||||||
{ label: 'Priority', id: 'priority' },
|
{ label: 'Group', id: 'group' },
|
||||||
{ label: 'Status', id: 'status' },
|
|
||||||
{ label: 'Ticket Type', id: 'ticket_type' },
|
|
||||||
],
|
],
|
||||||
|
required: true,
|
||||||
condition: {
|
condition: {
|
||||||
field: 'operation',
|
field: 'operation',
|
||||||
value: ['search'],
|
value: ['search'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'sortOrder',
|
id: 'sort',
|
||||||
title: 'Sort Order',
|
title: 'Sort',
|
||||||
type: 'dropdown',
|
type: 'dropdown',
|
||||||
options: [
|
options: [
|
||||||
{ label: 'Ascending', id: 'asc' },
|
{ label: 'Updated At (Asc)', id: 'updated_at' },
|
||||||
{ label: 'Descending', id: 'desc' },
|
{ label: 'Updated At (Desc)', id: '-updated_at' },
|
||||||
|
{ label: 'ID (Asc)', id: 'id' },
|
||||||
|
{ label: 'ID (Desc)', id: '-id' },
|
||||||
|
{ label: 'Status (Asc)', id: 'status' },
|
||||||
|
{ label: 'Status (Desc)', id: '-status' },
|
||||||
],
|
],
|
||||||
condition: {
|
condition: {
|
||||||
field: 'operation',
|
field: 'operation',
|
||||||
value: ['search'],
|
value: ['get_tickets'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Pagination fields
|
// Pagination fields
|
||||||
@@ -492,20 +495,25 @@ Return ONLY the search query - no explanations.`,
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'page',
|
id: 'pageAfter',
|
||||||
title: 'Page',
|
title: 'Page After (Cursor)',
|
||||||
type: 'short-input',
|
type: 'short-input',
|
||||||
placeholder: 'Page number',
|
placeholder: 'Cursor from previous response (after_cursor)',
|
||||||
|
description: 'Cursor value from a previous response to fetch the next page of results',
|
||||||
condition: {
|
condition: {
|
||||||
field: 'operation',
|
field: 'operation',
|
||||||
value: [
|
value: ['get_tickets', 'get_users', 'get_organizations', 'search'],
|
||||||
'get_tickets',
|
},
|
||||||
'get_users',
|
},
|
||||||
'get_organizations',
|
{
|
||||||
'search_users',
|
id: 'page',
|
||||||
'autocomplete_organizations',
|
title: 'Page Number',
|
||||||
'search',
|
type: 'short-input',
|
||||||
],
|
placeholder: 'Page number (default: 1)',
|
||||||
|
description: 'Page number for offset-based pagination',
|
||||||
|
condition: {
|
||||||
|
field: 'operation',
|
||||||
|
value: ['search_users', 'autocomplete_organizations'],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -624,6 +632,7 @@ Return ONLY the search query - no explanations.`,
|
|||||||
email: { type: 'string', description: 'Zendesk email address' },
|
email: { type: 'string', description: 'Zendesk email address' },
|
||||||
apiToken: { type: 'string', description: 'Zendesk API token' },
|
apiToken: { type: 'string', description: 'Zendesk API token' },
|
||||||
subdomain: { type: 'string', description: 'Zendesk subdomain' },
|
subdomain: { type: 'string', description: 'Zendesk subdomain' },
|
||||||
|
sort: { type: 'string', description: 'Sort field for ticket listing' },
|
||||||
},
|
},
|
||||||
outputs: {
|
outputs: {
|
||||||
// Ticket operations - list
|
// Ticket operations - list
|
||||||
@@ -665,8 +674,11 @@ Return ONLY the search query - no explanations.`,
|
|||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: 'Deletion confirmation (delete_ticket, delete_user, delete_organization)',
|
description: 'Deletion confirmation (delete_ticket, delete_user, delete_organization)',
|
||||||
},
|
},
|
||||||
// Pagination (shared across list operations)
|
// Cursor-based pagination (shared across list operations)
|
||||||
paging: { type: 'json', description: 'Pagination information for list operations' },
|
paging: {
|
||||||
|
type: 'json',
|
||||||
|
description: 'Cursor-based pagination information (after_cursor, has_more)',
|
||||||
|
},
|
||||||
// Metadata (shared across all operations)
|
// Metadata (shared across all operations)
|
||||||
metadata: { type: 'json', description: 'Operation metadata including operation type' },
|
metadata: { type: 'json', description: 'Operation metadata including operation type' },
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
type ReactNode,
|
type ReactNode,
|
||||||
useCallback,
|
useCallback,
|
||||||
useEffect,
|
useEffect,
|
||||||
|
useId,
|
||||||
useMemo,
|
useMemo,
|
||||||
useRef,
|
useRef,
|
||||||
useState,
|
useState,
|
||||||
@@ -170,6 +171,7 @@ const Combobox = memo(
|
|||||||
},
|
},
|
||||||
ref
|
ref
|
||||||
) => {
|
) => {
|
||||||
|
const listboxId = useId()
|
||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
const [highlightedIndex, setHighlightedIndex] = useState(-1)
|
const [highlightedIndex, setHighlightedIndex] = useState(-1)
|
||||||
const [searchQuery, setSearchQuery] = useState('')
|
const [searchQuery, setSearchQuery] = useState('')
|
||||||
@@ -513,6 +515,7 @@ const Combobox = memo(
|
|||||||
role='combobox'
|
role='combobox'
|
||||||
aria-expanded={open}
|
aria-expanded={open}
|
||||||
aria-haspopup='listbox'
|
aria-haspopup='listbox'
|
||||||
|
aria-controls={listboxId}
|
||||||
aria-disabled={disabled}
|
aria-disabled={disabled}
|
||||||
tabIndex={disabled ? -1 : 0}
|
tabIndex={disabled ? -1 : 0}
|
||||||
className={cn(
|
className={cn(
|
||||||
@@ -616,7 +619,7 @@ const Combobox = memo(
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div ref={dropdownRef} role='listbox'>
|
<div ref={dropdownRef} role='listbox' id={listboxId}>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<div className='flex items-center justify-center py-[14px]'>
|
<div className='flex items-center justify-center py-[14px]'>
|
||||||
<Loader2 className='h-[16px] w-[16px] animate-spin text-[var(--text-muted)]' />
|
<Loader2 className='h-[16px] w-[16px] animate-spin text-[var(--text-muted)]' />
|
||||||
|
|||||||
@@ -27,12 +27,14 @@ const Alert = React.forwardRef<
|
|||||||
Alert.displayName = 'Alert'
|
Alert.displayName = 'Alert'
|
||||||
|
|
||||||
const AlertTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
|
const AlertTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
|
||||||
({ className, ...props }, ref) => (
|
({ className, children, ...props }, ref) => (
|
||||||
<h5
|
<h5
|
||||||
ref={ref}
|
ref={ref}
|
||||||
className={cn('mb-1 font-medium leading-none tracking-tight', className)}
|
className={cn('mb-1 font-medium leading-none tracking-tight', className)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
>
|
||||||
|
{children}
|
||||||
|
</h5>
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
AlertTitle.displayName = 'AlertTitle'
|
AlertTitle.displayName = 'AlertTitle'
|
||||||
|
|||||||
@@ -16,26 +16,32 @@ export const mdxComponents: MDXRemoteProps['components'] = {
|
|||||||
unoptimized
|
unoptimized
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
h2: (props: any) => (
|
h2: ({ children, className, ...props }: any) => (
|
||||||
<h2
|
<h2
|
||||||
{...props}
|
{...props}
|
||||||
style={{ fontSize: '30px', marginTop: '3rem', marginBottom: '1.5rem' }}
|
style={{ fontSize: '30px', marginTop: '3rem', marginBottom: '1.5rem' }}
|
||||||
className={clsx('font-medium text-black leading-tight', props.className)}
|
className={clsx('font-medium text-black leading-tight', className)}
|
||||||
/>
|
>
|
||||||
|
{children}
|
||||||
|
</h2>
|
||||||
),
|
),
|
||||||
h3: (props: any) => (
|
h3: ({ children, className, ...props }: any) => (
|
||||||
<h3
|
<h3
|
||||||
{...props}
|
{...props}
|
||||||
style={{ fontSize: '24px', marginTop: '1.5rem', marginBottom: '0.75rem' }}
|
style={{ fontSize: '24px', marginTop: '1.5rem', marginBottom: '0.75rem' }}
|
||||||
className={clsx('font-medium leading-tight', props.className)}
|
className={clsx('font-medium leading-tight', className)}
|
||||||
/>
|
>
|
||||||
|
{children}
|
||||||
|
</h3>
|
||||||
),
|
),
|
||||||
h4: (props: any) => (
|
h4: ({ children, className, ...props }: any) => (
|
||||||
<h4
|
<h4
|
||||||
{...props}
|
{...props}
|
||||||
style={{ fontSize: '19px', marginTop: '1.5rem', marginBottom: '0.75rem' }}
|
style={{ fontSize: '19px', marginTop: '1.5rem', marginBottom: '0.75rem' }}
|
||||||
className={clsx('font-medium leading-tight', props.className)}
|
className={clsx('font-medium leading-tight', className)}
|
||||||
/>
|
>
|
||||||
|
{children}
|
||||||
|
</h4>
|
||||||
),
|
),
|
||||||
p: (props: any) => (
|
p: (props: any) => (
|
||||||
<p
|
<p
|
||||||
|
|||||||
@@ -107,5 +107,3 @@ if (typeof process !== 'undefined') {
|
|||||||
logger.info(`S3 copilot bucket: ${env.S3_COPILOT_BUCKET_NAME}`)
|
logger.info(`S3 copilot bucket: ${env.S3_COPILOT_BUCKET_NAME}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default ensureUploadsDirectory
|
|
||||||
|
|||||||
@@ -326,6 +326,18 @@ const nextConfig: NextConfig = {
|
|||||||
|
|
||||||
return redirects
|
return redirects
|
||||||
},
|
},
|
||||||
|
async rewrites() {
|
||||||
|
return [
|
||||||
|
...(isHosted
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
source: '/r/:shortCode',
|
||||||
|
destination: 'https://go.trybeluga.ai/:shortCode',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
]
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export default nextConfig
|
export default nextConfig
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
supportsNativeStructuredOutputs,
|
supportsNativeStructuredOutputs,
|
||||||
} from '@/providers/models'
|
} from '@/providers/models'
|
||||||
import type { ProviderRequest, ProviderResponse, TimeSegment } from '@/providers/types'
|
import type { ProviderRequest, ProviderResponse, TimeSegment } from '@/providers/types'
|
||||||
|
import { ProviderError } from '@/providers/types'
|
||||||
import {
|
import {
|
||||||
calculateCost,
|
calculateCost,
|
||||||
prepareToolExecution,
|
prepareToolExecution,
|
||||||
@@ -842,15 +843,11 @@ export async function executeAnthropicProviderRequest(
|
|||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
})
|
})
|
||||||
|
|
||||||
const enhancedError = new Error(error instanceof Error ? error.message : String(error))
|
throw new ProviderError(error instanceof Error ? error.message : String(error), {
|
||||||
// @ts-ignore
|
|
||||||
enhancedError.timing = {
|
|
||||||
startTime: providerStartTimeISO,
|
startTime: providerStartTimeISO,
|
||||||
endTime: providerEndTimeISO,
|
endTime: providerEndTimeISO,
|
||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
}
|
})
|
||||||
|
|
||||||
throw enhancedError
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1299,14 +1296,10 @@ export async function executeAnthropicProviderRequest(
|
|||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
})
|
})
|
||||||
|
|
||||||
const enhancedError = new Error(error instanceof Error ? error.message : String(error))
|
throw new ProviderError(error instanceof Error ? error.message : String(error), {
|
||||||
// @ts-ignore
|
|
||||||
enhancedError.timing = {
|
|
||||||
startTime: providerStartTimeISO,
|
startTime: providerStartTimeISO,
|
||||||
endTime: providerEndTimeISO,
|
endTime: providerEndTimeISO,
|
||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
}
|
})
|
||||||
|
|
||||||
throw enhancedError
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import type {
|
|||||||
ProviderResponse,
|
ProviderResponse,
|
||||||
TimeSegment,
|
TimeSegment,
|
||||||
} from '@/providers/types'
|
} from '@/providers/types'
|
||||||
|
import { ProviderError } from '@/providers/types'
|
||||||
import {
|
import {
|
||||||
calculateCost,
|
calculateCost,
|
||||||
prepareToolExecution,
|
prepareToolExecution,
|
||||||
@@ -251,7 +252,7 @@ async function executeChatCompletionsRequest(
|
|||||||
output: currentResponse.usage?.completion_tokens || 0,
|
output: currentResponse.usage?.completion_tokens || 0,
|
||||||
total: currentResponse.usage?.total_tokens || 0,
|
total: currentResponse.usage?.total_tokens || 0,
|
||||||
}
|
}
|
||||||
const toolCalls: (FunctionCallResponse & { success: boolean })[] = []
|
const toolCalls: FunctionCallResponse[] = []
|
||||||
const toolResults: Record<string, unknown>[] = []
|
const toolResults: Record<string, unknown>[] = []
|
||||||
const currentMessages = [...allMessages]
|
const currentMessages = [...allMessages]
|
||||||
let iterationCount = 0
|
let iterationCount = 0
|
||||||
@@ -577,15 +578,11 @@ async function executeChatCompletionsRequest(
|
|||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
})
|
})
|
||||||
|
|
||||||
const enhancedError = new Error(error instanceof Error ? error.message : String(error))
|
throw new ProviderError(error instanceof Error ? error.message : String(error), {
|
||||||
// @ts-ignore - Adding timing property to the error
|
|
||||||
enhancedError.timing = {
|
|
||||||
startTime: providerStartTimeISO,
|
startTime: providerStartTimeISO,
|
||||||
endTime: providerEndTimeISO,
|
endTime: providerEndTimeISO,
|
||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
}
|
})
|
||||||
|
|
||||||
throw enhancedError
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,11 +22,13 @@ import {
|
|||||||
} from '@/providers/bedrock/utils'
|
} from '@/providers/bedrock/utils'
|
||||||
import { getProviderDefaultModel, getProviderModels } from '@/providers/models'
|
import { getProviderDefaultModel, getProviderModels } from '@/providers/models'
|
||||||
import type {
|
import type {
|
||||||
|
FunctionCallResponse,
|
||||||
ProviderConfig,
|
ProviderConfig,
|
||||||
ProviderRequest,
|
ProviderRequest,
|
||||||
ProviderResponse,
|
ProviderResponse,
|
||||||
TimeSegment,
|
TimeSegment,
|
||||||
} from '@/providers/types'
|
} from '@/providers/types'
|
||||||
|
import { ProviderError } from '@/providers/types'
|
||||||
import {
|
import {
|
||||||
calculateCost,
|
calculateCost,
|
||||||
prepareToolExecution,
|
prepareToolExecution,
|
||||||
@@ -419,8 +421,8 @@ export const bedrockProvider: ProviderConfig = {
|
|||||||
pricing: initialCost.pricing,
|
pricing: initialCost.pricing,
|
||||||
}
|
}
|
||||||
|
|
||||||
const toolCalls: any[] = []
|
const toolCalls: FunctionCallResponse[] = []
|
||||||
const toolResults: any[] = []
|
const toolResults: Record<string, unknown>[] = []
|
||||||
const currentMessages = [...messages]
|
const currentMessages = [...messages]
|
||||||
let iterationCount = 0
|
let iterationCount = 0
|
||||||
let hasUsedForcedTool = false
|
let hasUsedForcedTool = false
|
||||||
@@ -561,7 +563,7 @@ export const bedrockProvider: ProviderConfig = {
|
|||||||
|
|
||||||
let resultContent: any
|
let resultContent: any
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
toolResults.push(result.output)
|
toolResults.push(result.output!)
|
||||||
resultContent = result.output
|
resultContent = result.output
|
||||||
} else {
|
} else {
|
||||||
resultContent = {
|
resultContent = {
|
||||||
@@ -903,15 +905,11 @@ export const bedrockProvider: ProviderConfig = {
|
|||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
})
|
})
|
||||||
|
|
||||||
const enhancedError = new Error(error instanceof Error ? error.message : String(error))
|
throw new ProviderError(error instanceof Error ? error.message : String(error), {
|
||||||
// @ts-ignore
|
|
||||||
enhancedError.timing = {
|
|
||||||
startTime: providerStartTimeISO,
|
startTime: providerStartTimeISO,
|
||||||
endTime: providerEndTimeISO,
|
endTime: providerEndTimeISO,
|
||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
}
|
})
|
||||||
|
|
||||||
throw enhancedError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import type {
|
|||||||
ProviderResponse,
|
ProviderResponse,
|
||||||
TimeSegment,
|
TimeSegment,
|
||||||
} from '@/providers/types'
|
} from '@/providers/types'
|
||||||
|
import { ProviderError } from '@/providers/types'
|
||||||
import {
|
import {
|
||||||
calculateCost,
|
calculateCost,
|
||||||
prepareToolExecution,
|
prepareToolExecution,
|
||||||
@@ -539,15 +540,11 @@ export const cerebrasProvider: ProviderConfig = {
|
|||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
})
|
})
|
||||||
|
|
||||||
const enhancedError = new Error(error instanceof Error ? error.message : String(error))
|
throw new ProviderError(error instanceof Error ? error.message : String(error), {
|
||||||
// @ts-ignore - Adding timing property to error for debugging
|
|
||||||
enhancedError.timing = {
|
|
||||||
startTime: providerStartTimeISO,
|
startTime: providerStartTimeISO,
|
||||||
endTime: providerEndTimeISO,
|
endTime: providerEndTimeISO,
|
||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
}
|
})
|
||||||
|
|
||||||
throw enhancedError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import type {
|
|||||||
ProviderResponse,
|
ProviderResponse,
|
||||||
TimeSegment,
|
TimeSegment,
|
||||||
} from '@/providers/types'
|
} from '@/providers/types'
|
||||||
|
import { ProviderError } from '@/providers/types'
|
||||||
import {
|
import {
|
||||||
calculateCost,
|
calculateCost,
|
||||||
prepareToolExecution,
|
prepareToolExecution,
|
||||||
@@ -538,15 +539,11 @@ export const deepseekProvider: ProviderConfig = {
|
|||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
})
|
})
|
||||||
|
|
||||||
const enhancedError = new Error(error instanceof Error ? error.message : String(error))
|
throw new ProviderError(error instanceof Error ? error.message : String(error), {
|
||||||
// @ts-ignore
|
|
||||||
enhancedError.timing = {
|
|
||||||
startTime: providerStartTimeISO,
|
startTime: providerStartTimeISO,
|
||||||
endTime: providerEndTimeISO,
|
endTime: providerEndTimeISO,
|
||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
}
|
})
|
||||||
|
|
||||||
throw enhancedError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import type {
|
|||||||
ProviderResponse,
|
ProviderResponse,
|
||||||
TimeSegment,
|
TimeSegment,
|
||||||
} from '@/providers/types'
|
} from '@/providers/types'
|
||||||
|
import { ProviderError } from '@/providers/types'
|
||||||
import {
|
import {
|
||||||
calculateCost,
|
calculateCost,
|
||||||
prepareToolExecution,
|
prepareToolExecution,
|
||||||
@@ -496,15 +497,11 @@ export const groqProvider: ProviderConfig = {
|
|||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
})
|
})
|
||||||
|
|
||||||
const enhancedError = new Error(error instanceof Error ? error.message : String(error))
|
throw new ProviderError(error instanceof Error ? error.message : String(error), {
|
||||||
// @ts-ignore
|
|
||||||
enhancedError.timing = {
|
|
||||||
startTime: providerStartTimeISO,
|
startTime: providerStartTimeISO,
|
||||||
endTime: providerEndTimeISO,
|
endTime: providerEndTimeISO,
|
||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
}
|
})
|
||||||
|
|
||||||
throw enhancedError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import type {
|
|||||||
ProviderResponse,
|
ProviderResponse,
|
||||||
TimeSegment,
|
TimeSegment,
|
||||||
} from '@/providers/types'
|
} from '@/providers/types'
|
||||||
|
import { ProviderError } from '@/providers/types'
|
||||||
import {
|
import {
|
||||||
calculateCost,
|
calculateCost,
|
||||||
prepareToolExecution,
|
prepareToolExecution,
|
||||||
@@ -551,15 +552,11 @@ export const mistralProvider: ProviderConfig = {
|
|||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
})
|
})
|
||||||
|
|
||||||
const enhancedError = new Error(error instanceof Error ? error.message : String(error))
|
throw new ProviderError(error instanceof Error ? error.message : String(error), {
|
||||||
// @ts-ignore - Adding timing property to error for debugging
|
|
||||||
enhancedError.timing = {
|
|
||||||
startTime: providerStartTimeISO,
|
startTime: providerStartTimeISO,
|
||||||
endTime: providerEndTimeISO,
|
endTime: providerEndTimeISO,
|
||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
}
|
})
|
||||||
|
|
||||||
throw enhancedError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import type {
|
|||||||
ProviderResponse,
|
ProviderResponse,
|
||||||
TimeSegment,
|
TimeSegment,
|
||||||
} from '@/providers/types'
|
} from '@/providers/types'
|
||||||
|
import { ProviderError } from '@/providers/types'
|
||||||
import { calculateCost, prepareToolExecution } from '@/providers/utils'
|
import { calculateCost, prepareToolExecution } from '@/providers/utils'
|
||||||
import { useProvidersStore } from '@/stores/providers'
|
import { useProvidersStore } from '@/stores/providers'
|
||||||
import { executeTool } from '@/tools'
|
import { executeTool } from '@/tools'
|
||||||
@@ -554,15 +555,11 @@ export const ollamaProvider: ProviderConfig = {
|
|||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
})
|
})
|
||||||
|
|
||||||
const enhancedError = new Error(error instanceof Error ? error.message : String(error))
|
throw new ProviderError(error instanceof Error ? error.message : String(error), {
|
||||||
// @ts-ignore
|
|
||||||
enhancedError.timing = {
|
|
||||||
startTime: providerStartTimeISO,
|
startTime: providerStartTimeISO,
|
||||||
endTime: providerEndTimeISO,
|
endTime: providerEndTimeISO,
|
||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
}
|
})
|
||||||
|
|
||||||
throw enhancedError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import type OpenAI from 'openai'
|
|||||||
import type { StreamingExecution } from '@/executor/types'
|
import type { StreamingExecution } from '@/executor/types'
|
||||||
import { MAX_TOOL_ITERATIONS } from '@/providers'
|
import { MAX_TOOL_ITERATIONS } from '@/providers'
|
||||||
import type { Message, ProviderRequest, ProviderResponse, TimeSegment } from '@/providers/types'
|
import type { Message, ProviderRequest, ProviderResponse, TimeSegment } from '@/providers/types'
|
||||||
|
import { ProviderError } from '@/providers/types'
|
||||||
import {
|
import {
|
||||||
calculateCost,
|
calculateCost,
|
||||||
prepareToolExecution,
|
prepareToolExecution,
|
||||||
@@ -806,14 +807,10 @@ export async function executeResponsesProviderRequest(
|
|||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
})
|
})
|
||||||
|
|
||||||
const enhancedError = new Error(error instanceof Error ? error.message : String(error))
|
throw new ProviderError(error instanceof Error ? error.message : String(error), {
|
||||||
// @ts-ignore - Adding timing property to the error
|
|
||||||
enhancedError.timing = {
|
|
||||||
startTime: providerStartTimeISO,
|
startTime: providerStartTimeISO,
|
||||||
endTime: providerEndTimeISO,
|
endTime: providerEndTimeISO,
|
||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
}
|
})
|
||||||
|
|
||||||
throw enhancedError
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,14 @@ import {
|
|||||||
supportsNativeStructuredOutputs,
|
supportsNativeStructuredOutputs,
|
||||||
} from '@/providers/openrouter/utils'
|
} from '@/providers/openrouter/utils'
|
||||||
import type {
|
import type {
|
||||||
|
FunctionCallResponse,
|
||||||
|
Message,
|
||||||
ProviderConfig,
|
ProviderConfig,
|
||||||
ProviderRequest,
|
ProviderRequest,
|
||||||
ProviderResponse,
|
ProviderResponse,
|
||||||
TimeSegment,
|
TimeSegment,
|
||||||
} from '@/providers/types'
|
} from '@/providers/types'
|
||||||
|
import { ProviderError } from '@/providers/types'
|
||||||
import {
|
import {
|
||||||
calculateCost,
|
calculateCost,
|
||||||
generateSchemaInstructions,
|
generateSchemaInstructions,
|
||||||
@@ -90,7 +93,7 @@ export const openRouterProvider: ProviderConfig = {
|
|||||||
stream: !!request.stream,
|
stream: !!request.stream,
|
||||||
})
|
})
|
||||||
|
|
||||||
const allMessages = [] as any[]
|
const allMessages: Message[] = []
|
||||||
|
|
||||||
if (request.systemPrompt) {
|
if (request.systemPrompt) {
|
||||||
allMessages.push({ role: 'system', content: request.systemPrompt })
|
allMessages.push({ role: 'system', content: request.systemPrompt })
|
||||||
@@ -237,8 +240,8 @@ export const openRouterProvider: ProviderConfig = {
|
|||||||
output: currentResponse.usage?.completion_tokens || 0,
|
output: currentResponse.usage?.completion_tokens || 0,
|
||||||
total: currentResponse.usage?.total_tokens || 0,
|
total: currentResponse.usage?.total_tokens || 0,
|
||||||
}
|
}
|
||||||
const toolCalls = [] as any[]
|
const toolCalls: FunctionCallResponse[] = []
|
||||||
const toolResults = [] as any[]
|
const toolResults: Record<string, unknown>[] = []
|
||||||
const currentMessages = [...allMessages]
|
const currentMessages = [...allMessages]
|
||||||
let iterationCount = 0
|
let iterationCount = 0
|
||||||
let modelTime = firstResponseTime
|
let modelTime = firstResponseTime
|
||||||
@@ -352,7 +355,7 @@ export const openRouterProvider: ProviderConfig = {
|
|||||||
|
|
||||||
let resultContent: any
|
let resultContent: any
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
toolResults.push(result.output)
|
toolResults.push(result.output!)
|
||||||
resultContent = result.output
|
resultContent = result.output
|
||||||
} else {
|
} else {
|
||||||
resultContent = {
|
resultContent = {
|
||||||
@@ -593,14 +596,11 @@ export const openRouterProvider: ProviderConfig = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
logger.error('Error in OpenRouter request:', errorDetails)
|
logger.error('Error in OpenRouter request:', errorDetails)
|
||||||
const enhancedError = new Error(error instanceof Error ? error.message : String(error))
|
throw new ProviderError(error instanceof Error ? error.message : String(error), {
|
||||||
// @ts-ignore
|
|
||||||
enhancedError.timing = {
|
|
||||||
startTime: providerStartTimeISO,
|
startTime: providerStartTimeISO,
|
||||||
endTime: providerEndTimeISO,
|
endTime: providerEndTimeISO,
|
||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
}
|
})
|
||||||
throw enhancedError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ export interface FunctionCallResponse {
|
|||||||
result?: Record<string, any>
|
result?: Record<string, any>
|
||||||
output?: Record<string, any>
|
output?: Record<string, any>
|
||||||
input?: Record<string, any>
|
input?: Record<string, any>
|
||||||
|
success?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TimeSegment {
|
export interface TimeSegment {
|
||||||
@@ -177,4 +178,21 @@ export interface ProviderRequest {
|
|||||||
previousInteractionId?: string
|
previousInteractionId?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Typed error class for provider failures that includes timing information.
|
||||||
|
*/
|
||||||
|
export class ProviderError extends Error {
|
||||||
|
timing: {
|
||||||
|
startTime: string
|
||||||
|
endTime: string
|
||||||
|
duration: number
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(message: string, timing: { startTime: string; endTime: string; duration: number }) {
|
||||||
|
super(message)
|
||||||
|
this.name = 'ProviderError'
|
||||||
|
this.timing = timing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const providers: Record<string, ProviderConfig> = {}
|
export const providers: Record<string, ProviderConfig> = {}
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ import type { StreamingExecution } from '@/executor/types'
|
|||||||
import { MAX_TOOL_ITERATIONS } from '@/providers'
|
import { MAX_TOOL_ITERATIONS } from '@/providers'
|
||||||
import { getProviderDefaultModel, getProviderModels } from '@/providers/models'
|
import { getProviderDefaultModel, getProviderModels } from '@/providers/models'
|
||||||
import type {
|
import type {
|
||||||
|
Message,
|
||||||
ProviderConfig,
|
ProviderConfig,
|
||||||
ProviderRequest,
|
ProviderRequest,
|
||||||
ProviderResponse,
|
ProviderResponse,
|
||||||
TimeSegment,
|
TimeSegment,
|
||||||
} from '@/providers/types'
|
} from '@/providers/types'
|
||||||
|
import { ProviderError } from '@/providers/types'
|
||||||
import {
|
import {
|
||||||
calculateCost,
|
calculateCost,
|
||||||
prepareToolExecution,
|
prepareToolExecution,
|
||||||
@@ -98,7 +100,7 @@ export const vllmProvider: ProviderConfig = {
|
|||||||
baseURL: `${baseUrl}/v1`,
|
baseURL: `${baseUrl}/v1`,
|
||||||
})
|
})
|
||||||
|
|
||||||
const allMessages = [] as any[]
|
const allMessages: Message[] = []
|
||||||
|
|
||||||
if (request.systemPrompt) {
|
if (request.systemPrompt) {
|
||||||
allMessages.push({
|
allMessages.push({
|
||||||
@@ -635,23 +637,11 @@ export const vllmProvider: ProviderConfig = {
|
|||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
})
|
})
|
||||||
|
|
||||||
const enhancedError = new Error(errorMessage)
|
throw new ProviderError(errorMessage, {
|
||||||
// @ts-ignore
|
|
||||||
enhancedError.timing = {
|
|
||||||
startTime: providerStartTimeISO,
|
startTime: providerStartTimeISO,
|
||||||
endTime: providerEndTimeISO,
|
endTime: providerEndTimeISO,
|
||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
}
|
})
|
||||||
if (errorType) {
|
|
||||||
// @ts-ignore
|
|
||||||
enhancedError.vllmErrorType = errorType
|
|
||||||
}
|
|
||||||
if (errorCode) {
|
|
||||||
// @ts-ignore
|
|
||||||
enhancedError.vllmErrorCode = errorCode
|
|
||||||
}
|
|
||||||
|
|
||||||
throw enhancedError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import type { StreamingExecution } from '@/executor/types'
|
|||||||
import { MAX_TOOL_ITERATIONS } from '@/providers'
|
import { MAX_TOOL_ITERATIONS } from '@/providers'
|
||||||
import { getProviderDefaultModel, getProviderModels } from '@/providers/models'
|
import { getProviderDefaultModel, getProviderModels } from '@/providers/models'
|
||||||
import type {
|
import type {
|
||||||
|
Message,
|
||||||
ProviderConfig,
|
ProviderConfig,
|
||||||
ProviderRequest,
|
ProviderRequest,
|
||||||
ProviderResponse,
|
ProviderResponse,
|
||||||
TimeSegment,
|
TimeSegment,
|
||||||
} from '@/providers/types'
|
} from '@/providers/types'
|
||||||
|
import { ProviderError } from '@/providers/types'
|
||||||
import {
|
import {
|
||||||
calculateCost,
|
calculateCost,
|
||||||
prepareToolExecution,
|
prepareToolExecution,
|
||||||
@@ -52,7 +54,7 @@ export const xAIProvider: ProviderConfig = {
|
|||||||
streaming: !!request.stream,
|
streaming: !!request.stream,
|
||||||
})
|
})
|
||||||
|
|
||||||
const allMessages: any[] = []
|
const allMessages: Message[] = []
|
||||||
|
|
||||||
if (request.systemPrompt) {
|
if (request.systemPrompt) {
|
||||||
allMessages.push({
|
allMessages.push({
|
||||||
@@ -587,15 +589,11 @@ export const xAIProvider: ProviderConfig = {
|
|||||||
hasResponseFormat: !!request.responseFormat,
|
hasResponseFormat: !!request.responseFormat,
|
||||||
})
|
})
|
||||||
|
|
||||||
const enhancedError = new Error(error instanceof Error ? error.message : String(error))
|
throw new ProviderError(error instanceof Error ? error.message : String(error), {
|
||||||
// @ts-ignore - Adding timing property to error for debugging
|
|
||||||
enhancedError.timing = {
|
|
||||||
startTime: providerStartTimeISO,
|
startTime: providerStartTimeISO,
|
||||||
endTime: providerEndTimeISO,
|
endTime: providerEndTimeISO,
|
||||||
duration: totalDuration,
|
duration: totalDuration,
|
||||||
}
|
})
|
||||||
|
|
||||||
throw enhancedError
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,12 +26,6 @@ export const actionsListTool: ToolConfig<
|
|||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Filter actions by incident ID (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
description: 'Filter actions by incident ID (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||||
},
|
},
|
||||||
page_size: {
|
|
||||||
type: 'number',
|
|
||||||
required: false,
|
|
||||||
visibility: 'user-or-llm',
|
|
||||||
description: 'Number of actions to return per page (e.g., 10, 25, 50)',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
request: {
|
request: {
|
||||||
@@ -42,10 +36,6 @@ export const actionsListTool: ToolConfig<
|
|||||||
url.searchParams.append('incident_id', params.incident_id)
|
url.searchParams.append('incident_id', params.incident_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.page_size) {
|
|
||||||
url.searchParams.append('page_size', params.page_size.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
return url.toString()
|
return url.toString()
|
||||||
},
|
},
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
|||||||
@@ -20,22 +20,10 @@ export const escalationsListTool: ToolConfig<
|
|||||||
visibility: 'user-only',
|
visibility: 'user-only',
|
||||||
description: 'incident.io API Key',
|
description: 'incident.io API Key',
|
||||||
},
|
},
|
||||||
page_size: {
|
|
||||||
type: 'number',
|
|
||||||
required: false,
|
|
||||||
visibility: 'user-or-llm',
|
|
||||||
description: 'Number of results per page (e.g., 10, 25, 50). Default: 25',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
request: {
|
request: {
|
||||||
url: (params) => {
|
url: () => 'https://api.incident.io/v2/escalations',
|
||||||
const url = new URL('https://api.incident.io/v2/escalations')
|
|
||||||
if (params.page_size) {
|
|
||||||
url.searchParams.append('page_size', params.page_size.toString())
|
|
||||||
}
|
|
||||||
return url.toString()
|
|
||||||
},
|
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: (params) => ({
|
headers: (params) => ({
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|||||||
@@ -26,12 +26,6 @@ export const followUpsListTool: ToolConfig<
|
|||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Filter follow-ups by incident ID (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
description: 'Filter follow-ups by incident ID (e.g., "01FCNDV6P870EA6S7TK1DSYDG0")',
|
||||||
},
|
},
|
||||||
page_size: {
|
|
||||||
type: 'number',
|
|
||||||
required: false,
|
|
||||||
visibility: 'user-or-llm',
|
|
||||||
description: 'Number of follow-ups to return per page (e.g., 10, 25, 50)',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
request: {
|
request: {
|
||||||
@@ -42,10 +36,6 @@ export const followUpsListTool: ToolConfig<
|
|||||||
url.searchParams.append('incident_id', params.incident_id)
|
url.searchParams.append('incident_id', params.incident_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.page_size) {
|
|
||||||
url.searchParams.append('page_size', params.page_size.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
return url.toString()
|
return url.toString()
|
||||||
},
|
},
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
|||||||
@@ -396,7 +396,6 @@ export interface IncidentioIncidentsUpdateResponse extends ToolResponse {
|
|||||||
// Action types
|
// Action types
|
||||||
export interface IncidentioActionsListParams extends IncidentioBaseParams {
|
export interface IncidentioActionsListParams extends IncidentioBaseParams {
|
||||||
incident_id?: string
|
incident_id?: string
|
||||||
page_size?: number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IncidentioAction {
|
export interface IncidentioAction {
|
||||||
@@ -446,7 +445,6 @@ export interface IncidentioActionsShowResponse extends ToolResponse {
|
|||||||
// Follow-up types
|
// Follow-up types
|
||||||
export interface IncidentioFollowUpsListParams extends IncidentioBaseParams {
|
export interface IncidentioFollowUpsListParams extends IncidentioBaseParams {
|
||||||
incident_id?: string
|
incident_id?: string
|
||||||
page_size?: number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IncidentioFollowUp {
|
export interface IncidentioFollowUp {
|
||||||
@@ -664,6 +662,7 @@ export interface CustomFieldsDeleteResponse extends ToolResponse {
|
|||||||
// Users list tool types
|
// Users list tool types
|
||||||
export interface IncidentioUsersListParams extends IncidentioBaseParams {
|
export interface IncidentioUsersListParams extends IncidentioBaseParams {
|
||||||
page_size?: number
|
page_size?: number
|
||||||
|
after?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IncidentioUser {
|
export interface IncidentioUser {
|
||||||
@@ -676,6 +675,11 @@ export interface IncidentioUser {
|
|||||||
export interface IncidentioUsersListResponse extends ToolResponse {
|
export interface IncidentioUsersListResponse extends ToolResponse {
|
||||||
output: {
|
output: {
|
||||||
users: IncidentioUser[]
|
users: IncidentioUser[]
|
||||||
|
pagination_meta?: {
|
||||||
|
after: string
|
||||||
|
page_size: number
|
||||||
|
total_record_count?: number
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -786,9 +790,7 @@ export type IncidentioResponse =
|
|||||||
| IncidentioEscalationPathsDeleteResponse
|
| IncidentioEscalationPathsDeleteResponse
|
||||||
|
|
||||||
// Escalations types
|
// Escalations types
|
||||||
export interface IncidentioEscalationsListParams extends IncidentioBaseParams {
|
export interface IncidentioEscalationsListParams extends IncidentioBaseParams {}
|
||||||
page_size?: number
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IncidentioEscalation {
|
export interface IncidentioEscalation {
|
||||||
id: string
|
id: string
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import type {
|
import {
|
||||||
IncidentioUsersListParams,
|
INCIDENTIO_PAGINATION_OUTPUT_PROPERTIES,
|
||||||
IncidentioUsersListResponse,
|
type IncidentioUsersListParams,
|
||||||
|
type IncidentioUsersListResponse,
|
||||||
} from '@/tools/incidentio/types'
|
} from '@/tools/incidentio/types'
|
||||||
import type { ToolConfig } from '@/tools/types'
|
import type { ToolConfig } from '@/tools/types'
|
||||||
|
|
||||||
@@ -24,15 +25,27 @@ export const usersListTool: ToolConfig<IncidentioUsersListParams, IncidentioUser
|
|||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Number of results to return per page (e.g., 10, 25, 50). Default: 25',
|
description: 'Number of results to return per page (e.g., 10, 25, 50). Default: 25',
|
||||||
},
|
},
|
||||||
|
after: {
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
visibility: 'user-or-llm',
|
||||||
|
description: 'Pagination cursor to fetch the next page of results',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
request: {
|
request: {
|
||||||
url: (params) => {
|
url: (params) => {
|
||||||
const baseUrl = 'https://api.incident.io/v2/users'
|
const url = new URL('https://api.incident.io/v2/users')
|
||||||
|
|
||||||
if (params.page_size) {
|
if (params.page_size) {
|
||||||
return `${baseUrl}?page_size=${params.page_size}`
|
url.searchParams.append('page_size', params.page_size.toString())
|
||||||
}
|
}
|
||||||
return baseUrl
|
|
||||||
|
if (params.after) {
|
||||||
|
url.searchParams.append('after', params.after)
|
||||||
|
}
|
||||||
|
|
||||||
|
return url.toString()
|
||||||
},
|
},
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
headers: (params) => ({
|
headers: (params) => ({
|
||||||
@@ -53,6 +66,13 @@ export const usersListTool: ToolConfig<IncidentioUsersListParams, IncidentioUser
|
|||||||
email: user.email,
|
email: user.email,
|
||||||
role: user.role,
|
role: user.role,
|
||||||
})),
|
})),
|
||||||
|
pagination_meta: data.pagination_meta
|
||||||
|
? {
|
||||||
|
after: data.pagination_meta.after,
|
||||||
|
page_size: data.pagination_meta.page_size,
|
||||||
|
total_record_count: data.pagination_meta.total_record_count,
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -71,5 +91,11 @@ export const usersListTool: ToolConfig<IncidentioUsersListParams, IncidentioUser
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
pagination_meta: {
|
||||||
|
type: 'object',
|
||||||
|
description: 'Pagination metadata',
|
||||||
|
optional: true,
|
||||||
|
properties: INCIDENTIO_PAGINATION_OUTPUT_PROPERTIES,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,23 +24,11 @@ export const pipedriveGetActivitiesTool: ToolConfig<
|
|||||||
visibility: 'hidden',
|
visibility: 'hidden',
|
||||||
description: 'The access token for the Pipedrive API',
|
description: 'The access token for the Pipedrive API',
|
||||||
},
|
},
|
||||||
deal_id: {
|
user_id: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: false,
|
required: false,
|
||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Filter activities by deal ID (e.g., "123")',
|
description: 'Filter activities by user ID (e.g., "123")',
|
||||||
},
|
|
||||||
person_id: {
|
|
||||||
type: 'string',
|
|
||||||
required: false,
|
|
||||||
visibility: 'user-or-llm',
|
|
||||||
description: 'Filter activities by person ID (e.g., "456")',
|
|
||||||
},
|
|
||||||
org_id: {
|
|
||||||
type: 'string',
|
|
||||||
required: false,
|
|
||||||
visibility: 'user-or-llm',
|
|
||||||
description: 'Filter activities by organization ID (e.g., "789")',
|
|
||||||
},
|
},
|
||||||
type: {
|
type: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@@ -60,6 +48,12 @@ export const pipedriveGetActivitiesTool: ToolConfig<
|
|||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Number of results to return (e.g., "50", default: 100, max: 500)',
|
description: 'Number of results to return (e.g., "50", default: 100, max: 500)',
|
||||||
},
|
},
|
||||||
|
start: {
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
visibility: 'user-or-llm',
|
||||||
|
description: 'Pagination start offset (0-based index of the first item to return)',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
request: {
|
request: {
|
||||||
@@ -67,12 +61,11 @@ export const pipedriveGetActivitiesTool: ToolConfig<
|
|||||||
const baseUrl = 'https://api.pipedrive.com/v1/activities'
|
const baseUrl = 'https://api.pipedrive.com/v1/activities'
|
||||||
const queryParams = new URLSearchParams()
|
const queryParams = new URLSearchParams()
|
||||||
|
|
||||||
if (params.deal_id) queryParams.append('deal_id', params.deal_id)
|
if (params.user_id) queryParams.append('user_id', params.user_id)
|
||||||
if (params.person_id) queryParams.append('person_id', params.person_id)
|
|
||||||
if (params.org_id) queryParams.append('org_id', params.org_id)
|
|
||||||
if (params.type) queryParams.append('type', params.type)
|
if (params.type) queryParams.append('type', params.type)
|
||||||
if (params.done) queryParams.append('done', params.done)
|
if (params.done) queryParams.append('done', params.done)
|
||||||
if (params.limit) queryParams.append('limit', params.limit)
|
if (params.limit) queryParams.append('limit', params.limit)
|
||||||
|
if (params.start) queryParams.append('start', params.start)
|
||||||
|
|
||||||
const queryString = queryParams.toString()
|
const queryString = queryParams.toString()
|
||||||
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
||||||
@@ -99,12 +92,16 @@ export const pipedriveGetActivitiesTool: ToolConfig<
|
|||||||
}
|
}
|
||||||
|
|
||||||
const activities = data.data || []
|
const activities = data.data || []
|
||||||
|
const hasMore = data.additional_data?.pagination?.more_items_in_collection || false
|
||||||
|
const nextStart = data.additional_data?.pagination?.next_start ?? null
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
output: {
|
output: {
|
||||||
activities,
|
activities,
|
||||||
total_items: activities.length,
|
total_items: activities.length,
|
||||||
|
has_more: hasMore,
|
||||||
|
next_start: nextStart,
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -120,6 +117,16 @@ export const pipedriveGetActivitiesTool: ToolConfig<
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
total_items: { type: 'number', description: 'Total number of activities returned' },
|
total_items: { type: 'number', description: 'Total number of activities returned' },
|
||||||
|
has_more: {
|
||||||
|
type: 'boolean',
|
||||||
|
description: 'Whether more activities are available',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
next_start: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'Offset for fetching the next page',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
success: { type: 'boolean', description: 'Operation success status' },
|
success: { type: 'boolean', description: 'Operation success status' },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,12 @@ export const pipedriveGetAllDealsTool: ToolConfig<
|
|||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Number of results to return (e.g., "50", default: 100, max: 500)',
|
description: 'Number of results to return (e.g., "50", default: 100, max: 500)',
|
||||||
},
|
},
|
||||||
|
cursor: {
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
visibility: 'user-or-llm',
|
||||||
|
description: 'For pagination, the marker representing the first item on the next page',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
request: {
|
request: {
|
||||||
@@ -81,6 +87,7 @@ export const pipedriveGetAllDealsTool: ToolConfig<
|
|||||||
if (params.pipeline_id) queryParams.append('pipeline_id', params.pipeline_id)
|
if (params.pipeline_id) queryParams.append('pipeline_id', params.pipeline_id)
|
||||||
if (params.updated_since) queryParams.append('updated_since', params.updated_since)
|
if (params.updated_since) queryParams.append('updated_since', params.updated_since)
|
||||||
if (params.limit) queryParams.append('limit', params.limit)
|
if (params.limit) queryParams.append('limit', params.limit)
|
||||||
|
if (params.cursor) queryParams.append('cursor', params.cursor)
|
||||||
|
|
||||||
const queryString = queryParams.toString()
|
const queryString = queryParams.toString()
|
||||||
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
||||||
@@ -107,7 +114,8 @@ export const pipedriveGetAllDealsTool: ToolConfig<
|
|||||||
}
|
}
|
||||||
|
|
||||||
const deals = data.data || []
|
const deals = data.data || []
|
||||||
const hasMore = data.additional_data?.pagination?.more_items_in_collection || false
|
const nextCursor = data.additional_data?.next_cursor ?? null
|
||||||
|
const hasMore = nextCursor !== null
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
@@ -116,6 +124,7 @@ export const pipedriveGetAllDealsTool: ToolConfig<
|
|||||||
metadata: {
|
metadata: {
|
||||||
total_items: deals.length,
|
total_items: deals.length,
|
||||||
has_more: hasMore,
|
has_more: hasMore,
|
||||||
|
next_cursor: nextCursor,
|
||||||
},
|
},
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -16,29 +16,23 @@ export const pipedriveGetFilesTool: ToolConfig<PipedriveGetFilesParams, Pipedriv
|
|||||||
visibility: 'hidden',
|
visibility: 'hidden',
|
||||||
description: 'The access token for the Pipedrive API',
|
description: 'The access token for the Pipedrive API',
|
||||||
},
|
},
|
||||||
deal_id: {
|
sort: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: false,
|
required: false,
|
||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Filter files by deal ID (e.g., "123")',
|
description: 'Sort files by field (supported: "id", "update_time")',
|
||||||
},
|
|
||||||
person_id: {
|
|
||||||
type: 'string',
|
|
||||||
required: false,
|
|
||||||
visibility: 'user-or-llm',
|
|
||||||
description: 'Filter files by person ID (e.g., "456")',
|
|
||||||
},
|
|
||||||
org_id: {
|
|
||||||
type: 'string',
|
|
||||||
required: false,
|
|
||||||
visibility: 'user-or-llm',
|
|
||||||
description: 'Filter files by organization ID (e.g., "789")',
|
|
||||||
},
|
},
|
||||||
limit: {
|
limit: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: false,
|
required: false,
|
||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Number of results to return (e.g., "50", default: 100, max: 500)',
|
description: 'Number of results to return (e.g., "50", default: 100, max: 100)',
|
||||||
|
},
|
||||||
|
start: {
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
visibility: 'user-or-llm',
|
||||||
|
description: 'Pagination start offset (0-based index of the first item to return)',
|
||||||
},
|
},
|
||||||
downloadFiles: {
|
downloadFiles: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
@@ -56,10 +50,9 @@ export const pipedriveGetFilesTool: ToolConfig<PipedriveGetFilesParams, Pipedriv
|
|||||||
}),
|
}),
|
||||||
body: (params) => ({
|
body: (params) => ({
|
||||||
accessToken: params.accessToken,
|
accessToken: params.accessToken,
|
||||||
deal_id: params.deal_id,
|
sort: params.sort,
|
||||||
person_id: params.person_id,
|
|
||||||
org_id: params.org_id,
|
|
||||||
limit: params.limit,
|
limit: params.limit,
|
||||||
|
start: params.start,
|
||||||
downloadFiles: params.downloadFiles,
|
downloadFiles: params.downloadFiles,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
@@ -79,6 +72,16 @@ export const pipedriveGetFilesTool: ToolConfig<PipedriveGetFilesParams, Pipedriv
|
|||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
total_items: { type: 'number', description: 'Total number of files returned' },
|
total_items: { type: 'number', description: 'Total number of files returned' },
|
||||||
|
has_more: {
|
||||||
|
type: 'boolean',
|
||||||
|
description: 'Whether more files are available',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
next_start: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'Offset for fetching the next page',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
success: { type: 'boolean', description: 'Operation success status' },
|
success: { type: 'boolean', description: 'Operation success status' },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,12 @@ export const pipedriveGetLeadsTool: ToolConfig<PipedriveGetLeadsParams, Pipedriv
|
|||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Number of results to return (e.g., "50", default: 100, max: 500)',
|
description: 'Number of results to return (e.g., "50", default: 100, max: 500)',
|
||||||
},
|
},
|
||||||
|
start: {
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
visibility: 'user-or-llm',
|
||||||
|
description: 'Pagination start offset (0-based index of the first item to return)',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
request: {
|
request: {
|
||||||
@@ -81,6 +87,7 @@ export const pipedriveGetLeadsTool: ToolConfig<PipedriveGetLeadsParams, Pipedriv
|
|||||||
if (params.person_id) queryParams.append('person_id', params.person_id)
|
if (params.person_id) queryParams.append('person_id', params.person_id)
|
||||||
if (params.organization_id) queryParams.append('organization_id', params.organization_id)
|
if (params.organization_id) queryParams.append('organization_id', params.organization_id)
|
||||||
if (params.limit) queryParams.append('limit', params.limit)
|
if (params.limit) queryParams.append('limit', params.limit)
|
||||||
|
if (params.start) queryParams.append('start', params.start)
|
||||||
|
|
||||||
const queryString = queryParams.toString()
|
const queryString = queryParams.toString()
|
||||||
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
||||||
@@ -119,12 +126,19 @@ export const pipedriveGetLeadsTool: ToolConfig<PipedriveGetLeadsParams, Pipedriv
|
|||||||
|
|
||||||
// Otherwise, return list of leads
|
// Otherwise, return list of leads
|
||||||
const leads = data.data || []
|
const leads = data.data || []
|
||||||
|
// Leads endpoint puts pagination fields directly on additional_data (no .pagination wrapper)
|
||||||
|
const hasMore = data.additional_data?.more_items_in_collection || false
|
||||||
|
const currentStart = data.additional_data?.start ?? 0
|
||||||
|
const currentLimit = data.additional_data?.limit ?? leads.length
|
||||||
|
const nextStart = hasMore ? currentStart + currentLimit : null
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
output: {
|
output: {
|
||||||
leads,
|
leads,
|
||||||
total_items: leads.length,
|
total_items: leads.length,
|
||||||
|
has_more: hasMore,
|
||||||
|
next_start: nextStart,
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -151,6 +165,16 @@ export const pipedriveGetLeadsTool: ToolConfig<PipedriveGetLeadsParams, Pipedriv
|
|||||||
description: 'Total number of leads returned',
|
description: 'Total number of leads returned',
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
has_more: {
|
||||||
|
type: 'boolean',
|
||||||
|
description: 'Whether more leads are available',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
next_start: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'Offset for fetching the next page',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
success: { type: 'boolean', description: 'Operation success status' },
|
success: { type: 'boolean', description: 'Operation success status' },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,12 @@ export const pipedriveGetMailMessagesTool: ToolConfig<
|
|||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Number of results to return (e.g., "25", default: 50)',
|
description: 'Number of results to return (e.g., "25", default: 50)',
|
||||||
},
|
},
|
||||||
|
start: {
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
visibility: 'user-or-llm',
|
||||||
|
description: 'Pagination start offset (0-based index of the first item to return)',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
request: {
|
request: {
|
||||||
@@ -49,6 +55,7 @@ export const pipedriveGetMailMessagesTool: ToolConfig<
|
|||||||
|
|
||||||
if (params.folder) queryParams.append('folder', params.folder)
|
if (params.folder) queryParams.append('folder', params.folder)
|
||||||
if (params.limit) queryParams.append('limit', params.limit)
|
if (params.limit) queryParams.append('limit', params.limit)
|
||||||
|
if (params.start) queryParams.append('start', params.start)
|
||||||
|
|
||||||
const queryString = queryParams.toString()
|
const queryString = queryParams.toString()
|
||||||
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
||||||
@@ -75,12 +82,16 @@ export const pipedriveGetMailMessagesTool: ToolConfig<
|
|||||||
}
|
}
|
||||||
|
|
||||||
const threads = data.data || []
|
const threads = data.data || []
|
||||||
|
const hasMore = data.additional_data?.pagination?.more_items_in_collection || false
|
||||||
|
const nextStart = data.additional_data?.pagination?.next_start ?? null
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
output: {
|
output: {
|
||||||
messages: threads,
|
messages: threads,
|
||||||
total_items: threads.length,
|
total_items: threads.length,
|
||||||
|
has_more: hasMore,
|
||||||
|
next_start: nextStart,
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -89,6 +100,16 @@ export const pipedriveGetMailMessagesTool: ToolConfig<
|
|||||||
outputs: {
|
outputs: {
|
||||||
messages: { type: 'array', description: 'Array of mail thread objects from Pipedrive mailbox' },
|
messages: { type: 'array', description: 'Array of mail thread objects from Pipedrive mailbox' },
|
||||||
total_items: { type: 'number', description: 'Total number of mail threads returned' },
|
total_items: { type: 'number', description: 'Total number of mail threads returned' },
|
||||||
|
has_more: {
|
||||||
|
type: 'boolean',
|
||||||
|
description: 'Whether more messages are available',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
next_start: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'Offset for fetching the next page',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
success: { type: 'boolean', description: 'Operation success status' },
|
success: { type: 'boolean', description: 'Operation success status' },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,18 +35,18 @@ export const pipedriveGetPipelineDealsTool: ToolConfig<
|
|||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Filter by specific stage within the pipeline (e.g., "2")',
|
description: 'Filter by specific stage within the pipeline (e.g., "2")',
|
||||||
},
|
},
|
||||||
status: {
|
|
||||||
type: 'string',
|
|
||||||
required: false,
|
|
||||||
visibility: 'user-or-llm',
|
|
||||||
description: 'Filter by deal status: open, won, lost',
|
|
||||||
},
|
|
||||||
limit: {
|
limit: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: false,
|
required: false,
|
||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Number of results to return (e.g., "50", default: 100, max: 500)',
|
description: 'Number of results to return (e.g., "50", default: 100, max: 500)',
|
||||||
},
|
},
|
||||||
|
start: {
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
visibility: 'user-or-llm',
|
||||||
|
description: 'Pagination start offset (0-based index of the first item to return)',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
request: {
|
request: {
|
||||||
@@ -55,8 +55,8 @@ export const pipedriveGetPipelineDealsTool: ToolConfig<
|
|||||||
const queryParams = new URLSearchParams()
|
const queryParams = new URLSearchParams()
|
||||||
|
|
||||||
if (params.stage_id) queryParams.append('stage_id', params.stage_id)
|
if (params.stage_id) queryParams.append('stage_id', params.stage_id)
|
||||||
if (params.status) queryParams.append('status', params.status)
|
|
||||||
if (params.limit) queryParams.append('limit', params.limit)
|
if (params.limit) queryParams.append('limit', params.limit)
|
||||||
|
if (params.start) queryParams.append('start', params.start)
|
||||||
|
|
||||||
const queryString = queryParams.toString()
|
const queryString = queryParams.toString()
|
||||||
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
||||||
@@ -83,6 +83,8 @@ export const pipedriveGetPipelineDealsTool: ToolConfig<
|
|||||||
}
|
}
|
||||||
|
|
||||||
const deals = data.data || []
|
const deals = data.data || []
|
||||||
|
const hasMore = data.additional_data?.pagination?.more_items_in_collection || false
|
||||||
|
const nextStart = data.additional_data?.pagination?.next_start ?? null
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
@@ -91,6 +93,8 @@ export const pipedriveGetPipelineDealsTool: ToolConfig<
|
|||||||
metadata: {
|
metadata: {
|
||||||
pipeline_id: params?.pipeline_id || '',
|
pipeline_id: params?.pipeline_id || '',
|
||||||
total_items: deals.length,
|
total_items: deals.length,
|
||||||
|
has_more: hasMore,
|
||||||
|
next_start: nextStart,
|
||||||
},
|
},
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -42,11 +42,11 @@ export const pipedriveGetPipelinesTool: ToolConfig<
|
|||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Number of results to return (e.g., "50", default: 100, max: 500)',
|
description: 'Number of results to return (e.g., "50", default: 100, max: 500)',
|
||||||
},
|
},
|
||||||
cursor: {
|
start: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: false,
|
required: false,
|
||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'For pagination, the marker representing the first item on the next page',
|
description: 'Pagination start offset (0-based index of the first item to return)',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ export const pipedriveGetPipelinesTool: ToolConfig<
|
|||||||
if (params.sort_by) queryParams.append('sort_by', params.sort_by)
|
if (params.sort_by) queryParams.append('sort_by', params.sort_by)
|
||||||
if (params.sort_direction) queryParams.append('sort_direction', params.sort_direction)
|
if (params.sort_direction) queryParams.append('sort_direction', params.sort_direction)
|
||||||
if (params.limit) queryParams.append('limit', params.limit)
|
if (params.limit) queryParams.append('limit', params.limit)
|
||||||
if (params.cursor) queryParams.append('cursor', params.cursor)
|
if (params.start) queryParams.append('start', params.start)
|
||||||
|
|
||||||
const queryString = queryParams.toString()
|
const queryString = queryParams.toString()
|
||||||
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
||||||
@@ -85,12 +85,16 @@ export const pipedriveGetPipelinesTool: ToolConfig<
|
|||||||
}
|
}
|
||||||
|
|
||||||
const pipelines = data.data || []
|
const pipelines = data.data || []
|
||||||
|
const hasMore = data.additional_data?.pagination?.more_items_in_collection || false
|
||||||
|
const nextStart = data.additional_data?.pagination?.next_start ?? null
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
output: {
|
output: {
|
||||||
pipelines,
|
pipelines,
|
||||||
total_items: pipelines.length,
|
total_items: pipelines.length,
|
||||||
|
has_more: hasMore,
|
||||||
|
next_start: nextStart,
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -106,6 +110,16 @@ export const pipedriveGetPipelinesTool: ToolConfig<
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
total_items: { type: 'number', description: 'Total number of pipelines returned' },
|
total_items: { type: 'number', description: 'Total number of pipelines returned' },
|
||||||
|
has_more: {
|
||||||
|
type: 'boolean',
|
||||||
|
description: 'Whether more pipelines are available',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
next_start: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'Offset for fetching the next page',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
success: { type: 'boolean', description: 'Operation success status' },
|
success: { type: 'boolean', description: 'Operation success status' },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,12 @@ export const pipedriveGetProjectsTool: ToolConfig<
|
|||||||
description:
|
description:
|
||||||
'Number of results to return (e.g., "50", default: 100, max: 500, only for listing all)',
|
'Number of results to return (e.g., "50", default: 100, max: 500, only for listing all)',
|
||||||
},
|
},
|
||||||
|
cursor: {
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
visibility: 'user-or-llm',
|
||||||
|
description: 'For pagination, the marker representing the first item on the next page',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
request: {
|
request: {
|
||||||
@@ -57,6 +63,7 @@ export const pipedriveGetProjectsTool: ToolConfig<
|
|||||||
|
|
||||||
if (params.status) queryParams.append('status', params.status)
|
if (params.status) queryParams.append('status', params.status)
|
||||||
if (params.limit) queryParams.append('limit', params.limit)
|
if (params.limit) queryParams.append('limit', params.limit)
|
||||||
|
if (params.cursor) queryParams.append('cursor', params.cursor)
|
||||||
|
|
||||||
const queryString = queryParams.toString()
|
const queryString = queryParams.toString()
|
||||||
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
return queryString ? `${baseUrl}?${queryString}` : baseUrl
|
||||||
@@ -95,12 +102,16 @@ export const pipedriveGetProjectsTool: ToolConfig<
|
|||||||
|
|
||||||
// Otherwise, return list of projects
|
// Otherwise, return list of projects
|
||||||
const projects = data.data || []
|
const projects = data.data || []
|
||||||
|
const nextCursor = data.additional_data?.next_cursor ?? null
|
||||||
|
const hasMore = nextCursor !== null
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
output: {
|
output: {
|
||||||
projects,
|
projects,
|
||||||
total_items: projects.length,
|
total_items: projects.length,
|
||||||
|
has_more: hasMore,
|
||||||
|
next_cursor: nextCursor,
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -122,6 +133,16 @@ export const pipedriveGetProjectsTool: ToolConfig<
|
|||||||
description: 'Total number of projects returned',
|
description: 'Total number of projects returned',
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
|
has_more: {
|
||||||
|
type: 'boolean',
|
||||||
|
description: 'Whether more projects are available',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
next_cursor: {
|
||||||
|
type: 'string',
|
||||||
|
description: 'Cursor for fetching the next page',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
success: { type: 'boolean', description: 'Operation success status' },
|
success: { type: 'boolean', description: 'Operation success status' },
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,6 +239,16 @@ export const PIPEDRIVE_MAIL_MESSAGE_OUTPUT: OutputProperty = {
|
|||||||
export const PIPEDRIVE_METADATA_OUTPUT_PROPERTIES = {
|
export const PIPEDRIVE_METADATA_OUTPUT_PROPERTIES = {
|
||||||
total_items: { type: 'number', description: 'Total number of items' },
|
total_items: { type: 'number', description: 'Total number of items' },
|
||||||
has_more: { type: 'boolean', description: 'Whether more items are available', optional: true },
|
has_more: { type: 'boolean', description: 'Whether more items are available', optional: true },
|
||||||
|
next_cursor: {
|
||||||
|
type: 'string',
|
||||||
|
description: 'Cursor for fetching the next page (v2 endpoints)',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
|
next_start: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'Offset for fetching the next page (v1 endpoints)',
|
||||||
|
optional: true,
|
||||||
|
},
|
||||||
} as const satisfies Record<string, OutputProperty>
|
} as const satisfies Record<string, OutputProperty>
|
||||||
|
|
||||||
// Common Pipedrive types
|
// Common Pipedrive types
|
||||||
@@ -355,6 +365,7 @@ export interface PipedriveGetAllDealsParams {
|
|||||||
pipeline_id?: string
|
pipeline_id?: string
|
||||||
updated_since?: string
|
updated_since?: string
|
||||||
limit?: string
|
limit?: string
|
||||||
|
cursor?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PipedriveGetAllDealsOutput {
|
export interface PipedriveGetAllDealsOutput {
|
||||||
@@ -362,6 +373,7 @@ export interface PipedriveGetAllDealsOutput {
|
|||||||
metadata: {
|
metadata: {
|
||||||
total_items: number
|
total_items: number
|
||||||
has_more: boolean
|
has_more: boolean
|
||||||
|
next_cursor?: string
|
||||||
}
|
}
|
||||||
success: boolean
|
success: boolean
|
||||||
}
|
}
|
||||||
@@ -431,10 +443,9 @@ export interface PipedriveUpdateDealResponse extends ToolResponse {
|
|||||||
// GET Files
|
// GET Files
|
||||||
export interface PipedriveGetFilesParams {
|
export interface PipedriveGetFilesParams {
|
||||||
accessToken: string
|
accessToken: string
|
||||||
deal_id?: string
|
sort?: string
|
||||||
person_id?: string
|
|
||||||
org_id?: string
|
|
||||||
limit?: string
|
limit?: string
|
||||||
|
start?: string
|
||||||
downloadFiles?: boolean
|
downloadFiles?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,6 +453,8 @@ export interface PipedriveGetFilesOutput {
|
|||||||
files: PipedriveFile[]
|
files: PipedriveFile[]
|
||||||
downloadedFiles?: ToolFileData[]
|
downloadedFiles?: ToolFileData[]
|
||||||
total_items: number
|
total_items: number
|
||||||
|
has_more?: boolean
|
||||||
|
next_start?: number
|
||||||
success: boolean
|
success: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -453,11 +466,14 @@ export interface PipedriveGetMailMessagesParams {
|
|||||||
accessToken: string
|
accessToken: string
|
||||||
folder?: string
|
folder?: string
|
||||||
limit?: string
|
limit?: string
|
||||||
|
start?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PipedriveGetMailMessagesOutput {
|
export interface PipedriveGetMailMessagesOutput {
|
||||||
messages: PipedriveMailMessage[]
|
messages: PipedriveMailMessage[]
|
||||||
total_items: number
|
total_items: number
|
||||||
|
has_more?: boolean
|
||||||
|
next_start?: number
|
||||||
success: boolean
|
success: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,12 +506,14 @@ export interface PipedriveGetPipelinesParams {
|
|||||||
sort_by?: string
|
sort_by?: string
|
||||||
sort_direction?: string
|
sort_direction?: string
|
||||||
limit?: string
|
limit?: string
|
||||||
cursor?: string
|
start?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PipedriveGetPipelinesOutput {
|
export interface PipedriveGetPipelinesOutput {
|
||||||
pipelines: PipedrivePipeline[]
|
pipelines: PipedrivePipeline[]
|
||||||
total_items: number
|
total_items: number
|
||||||
|
has_more?: boolean
|
||||||
|
next_start?: number
|
||||||
success: boolean
|
success: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,8 +526,8 @@ export interface PipedriveGetPipelineDealsParams {
|
|||||||
accessToken: string
|
accessToken: string
|
||||||
pipeline_id: string
|
pipeline_id: string
|
||||||
stage_id?: string
|
stage_id?: string
|
||||||
status?: string
|
|
||||||
limit?: string
|
limit?: string
|
||||||
|
start?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PipedriveGetPipelineDealsOutput {
|
export interface PipedriveGetPipelineDealsOutput {
|
||||||
@@ -517,6 +535,8 @@ export interface PipedriveGetPipelineDealsOutput {
|
|||||||
metadata: {
|
metadata: {
|
||||||
pipeline_id: string
|
pipeline_id: string
|
||||||
total_items: number
|
total_items: number
|
||||||
|
has_more?: boolean
|
||||||
|
next_start?: number
|
||||||
}
|
}
|
||||||
success: boolean
|
success: boolean
|
||||||
}
|
}
|
||||||
@@ -531,12 +551,15 @@ export interface PipedriveGetProjectsParams {
|
|||||||
project_id?: string
|
project_id?: string
|
||||||
status?: string
|
status?: string
|
||||||
limit?: string
|
limit?: string
|
||||||
|
cursor?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PipedriveGetProjectsOutput {
|
export interface PipedriveGetProjectsOutput {
|
||||||
projects?: PipedriveProject[]
|
projects?: PipedriveProject[]
|
||||||
project?: PipedriveProject
|
project?: PipedriveProject
|
||||||
total_items?: number
|
total_items?: number
|
||||||
|
has_more?: boolean
|
||||||
|
next_cursor?: string
|
||||||
success: boolean
|
success: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -565,17 +588,18 @@ export interface PipedriveCreateProjectResponse extends ToolResponse {
|
|||||||
// GET All Activities
|
// GET All Activities
|
||||||
export interface PipedriveGetActivitiesParams {
|
export interface PipedriveGetActivitiesParams {
|
||||||
accessToken: string
|
accessToken: string
|
||||||
deal_id?: string
|
user_id?: string
|
||||||
person_id?: string
|
|
||||||
org_id?: string
|
|
||||||
type?: string
|
type?: string
|
||||||
done?: string
|
done?: string
|
||||||
limit?: string
|
limit?: string
|
||||||
|
start?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PipedriveGetActivitiesOutput {
|
export interface PipedriveGetActivitiesOutput {
|
||||||
activities: PipedriveActivity[]
|
activities: PipedriveActivity[]
|
||||||
total_items: number
|
total_items: number
|
||||||
|
has_more?: boolean
|
||||||
|
next_start?: number
|
||||||
success: boolean
|
success: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -636,12 +660,15 @@ export interface PipedriveGetLeadsParams {
|
|||||||
person_id?: string
|
person_id?: string
|
||||||
organization_id?: string
|
organization_id?: string
|
||||||
limit?: string
|
limit?: string
|
||||||
|
start?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PipedriveGetLeadsOutput {
|
export interface PipedriveGetLeadsOutput {
|
||||||
leads?: PipedriveLead[]
|
leads?: PipedriveLead[]
|
||||||
lead?: PipedriveLead
|
lead?: PipedriveLead
|
||||||
total_items?: number
|
total_items?: number
|
||||||
|
has_more?: boolean
|
||||||
|
next_start?: number
|
||||||
success: boolean
|
success: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,6 +51,12 @@ export const queryTool: ToolConfig<SupabaseQueryParams, SupabaseQueryResponse> =
|
|||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Maximum number of rows to return',
|
description: 'Maximum number of rows to return',
|
||||||
},
|
},
|
||||||
|
offset: {
|
||||||
|
type: 'number',
|
||||||
|
required: false,
|
||||||
|
visibility: 'user-or-llm',
|
||||||
|
description: 'Number of rows to skip (for pagination)',
|
||||||
|
},
|
||||||
apiKey: {
|
apiKey: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: true,
|
required: true,
|
||||||
@@ -91,10 +97,15 @@ export const queryTool: ToolConfig<SupabaseQueryParams, SupabaseQueryResponse> =
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add limit if provided
|
// Add limit if provided
|
||||||
if (params.limit) {
|
if (params.limit !== undefined && params.limit !== null) {
|
||||||
url += `&limit=${Number(params.limit)}`
|
url += `&limit=${Number(params.limit)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add offset if provided
|
||||||
|
if (params.offset !== undefined && params.offset !== null) {
|
||||||
|
url += `&offset=${Number(params.offset)}`
|
||||||
|
}
|
||||||
|
|
||||||
return url
|
return url
|
||||||
},
|
},
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
|||||||
@@ -57,6 +57,12 @@ export const textSearchTool: ToolConfig<SupabaseTextSearchParams, SupabaseTextSe
|
|||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Maximum number of rows to return',
|
description: 'Maximum number of rows to return',
|
||||||
},
|
},
|
||||||
|
offset: {
|
||||||
|
type: 'number',
|
||||||
|
required: false,
|
||||||
|
visibility: 'user-or-llm',
|
||||||
|
description: 'Number of rows to skip (for pagination)',
|
||||||
|
},
|
||||||
apiKey: {
|
apiKey: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: true,
|
required: true,
|
||||||
@@ -74,8 +80,9 @@ export const textSearchTool: ToolConfig<SupabaseTextSearchParams, SupabaseTextSe
|
|||||||
let url = `https://${params.projectId}.supabase.co/rest/v1/${params.table}?select=*`
|
let url = `https://${params.projectId}.supabase.co/rest/v1/${params.table}?select=*`
|
||||||
|
|
||||||
// Map search types to PostgREST operators
|
// Map search types to PostgREST operators
|
||||||
|
// plfts = plainto_tsquery (natural language), phfts = phraseto_tsquery, wfts = websearch_to_tsquery
|
||||||
const operatorMap: Record<string, string> = {
|
const operatorMap: Record<string, string> = {
|
||||||
plain: 'fts',
|
plain: 'plfts',
|
||||||
phrase: 'phfts',
|
phrase: 'phfts',
|
||||||
websearch: 'wfts',
|
websearch: 'wfts',
|
||||||
}
|
}
|
||||||
@@ -86,10 +93,15 @@ export const textSearchTool: ToolConfig<SupabaseTextSearchParams, SupabaseTextSe
|
|||||||
url += `&${params.column}=${operator}(${language}).${encodeURIComponent(params.query)}`
|
url += `&${params.column}=${operator}(${language}).${encodeURIComponent(params.query)}`
|
||||||
|
|
||||||
// Add limit if provided
|
// Add limit if provided
|
||||||
if (params.limit) {
|
if (params.limit !== undefined && params.limit !== null) {
|
||||||
url += `&limit=${Number(params.limit)}`
|
url += `&limit=${Number(params.limit)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add offset if provided
|
||||||
|
if (params.offset !== undefined && params.offset !== null) {
|
||||||
|
url += `&offset=${Number(params.offset)}`
|
||||||
|
}
|
||||||
|
|
||||||
return url
|
return url
|
||||||
},
|
},
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
|||||||
@@ -315,6 +315,7 @@ export interface SupabaseQueryParams {
|
|||||||
filter?: string
|
filter?: string
|
||||||
orderBy?: string
|
orderBy?: string
|
||||||
limit?: number
|
limit?: number
|
||||||
|
offset?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SupabaseInsertParams {
|
export interface SupabaseInsertParams {
|
||||||
@@ -413,6 +414,7 @@ export interface SupabaseTextSearchParams {
|
|||||||
searchType?: string
|
searchType?: string
|
||||||
language?: string
|
language?: string
|
||||||
limit?: number
|
limit?: number
|
||||||
|
offset?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SupabaseTextSearchResponse extends SupabaseBaseResponse {}
|
export interface SupabaseTextSearchResponse extends SupabaseBaseResponse {}
|
||||||
|
|||||||
@@ -26,6 +26,18 @@ export const responsesTool: ToolConfig<TypeformResponsesParams, TypeformResponse
|
|||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Number of responses to retrieve (e.g., 10, 25, 50)',
|
description: 'Number of responses to retrieve (e.g., 10, 25, 50)',
|
||||||
},
|
},
|
||||||
|
before: {
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
visibility: 'user-or-llm',
|
||||||
|
description: 'Cursor token for fetching the next page of older responses',
|
||||||
|
},
|
||||||
|
after: {
|
||||||
|
type: 'string',
|
||||||
|
required: false,
|
||||||
|
visibility: 'user-or-llm',
|
||||||
|
description: 'Cursor token for fetching the next page of newer responses',
|
||||||
|
},
|
||||||
since: {
|
since: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: false,
|
required: false,
|
||||||
@@ -56,6 +68,14 @@ export const responsesTool: ToolConfig<TypeformResponsesParams, TypeformResponse
|
|||||||
queryParams.push(`page_size=${Number(params.pageSize)}`)
|
queryParams.push(`page_size=${Number(params.pageSize)}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (params.before) {
|
||||||
|
queryParams.push(`before=${encodeURIComponent(params.before)}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params.after) {
|
||||||
|
queryParams.push(`after=${encodeURIComponent(params.after)}`)
|
||||||
|
}
|
||||||
|
|
||||||
if (params.since) {
|
if (params.since) {
|
||||||
queryParams.push(`since=${encodeURIComponent(params.since)}`)
|
queryParams.push(`since=${encodeURIComponent(params.since)}`)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ export interface TypeformResponsesParams {
|
|||||||
formId: string
|
formId: string
|
||||||
apiKey: string
|
apiKey: string
|
||||||
pageSize?: number
|
pageSize?: number
|
||||||
|
before?: string
|
||||||
|
after?: string
|
||||||
since?: string
|
since?: string
|
||||||
until?: string
|
until?: string
|
||||||
completed?: string
|
completed?: string
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ export interface ZendeskAutocompleteOrganizationsResponse {
|
|||||||
output: {
|
output: {
|
||||||
organizations: any[]
|
organizations: any[]
|
||||||
paging?: {
|
paging?: {
|
||||||
|
after_cursor: string | null
|
||||||
|
has_more: boolean
|
||||||
next_page?: string | null
|
next_page?: string | null
|
||||||
previous_page?: string | null
|
|
||||||
count: number
|
|
||||||
}
|
}
|
||||||
metadata: {
|
metadata: {
|
||||||
total_returned: number
|
total_returned: number
|
||||||
@@ -78,7 +78,7 @@ export const zendeskAutocompleteOrganizationsTool: ToolConfig<
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
required: false,
|
required: false,
|
||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Page number as a string (e.g., "1", "2")',
|
description: 'Page number for pagination (1-based)',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -86,8 +86,8 @@ export const zendeskAutocompleteOrganizationsTool: ToolConfig<
|
|||||||
url: (params) => {
|
url: (params) => {
|
||||||
const queryParams = new URLSearchParams()
|
const queryParams = new URLSearchParams()
|
||||||
queryParams.append('name', params.name)
|
queryParams.append('name', params.name)
|
||||||
if (params.page) queryParams.append('page', params.page)
|
|
||||||
if (params.perPage) queryParams.append('per_page', params.perPage)
|
if (params.perPage) queryParams.append('per_page', params.perPage)
|
||||||
|
if (params.page) queryParams.append('page', params.page)
|
||||||
|
|
||||||
const query = queryParams.toString()
|
const query = queryParams.toString()
|
||||||
const url = buildZendeskUrl(params.subdomain, '/organizations/autocomplete')
|
const url = buildZendeskUrl(params.subdomain, '/organizations/autocomplete')
|
||||||
@@ -112,19 +112,22 @@ export const zendeskAutocompleteOrganizationsTool: ToolConfig<
|
|||||||
|
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
const organizations = data.organizations || []
|
const organizations = data.organizations || []
|
||||||
|
const hasMore = data.next_page !== null && data.next_page !== undefined
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
output: {
|
output: {
|
||||||
organizations,
|
organizations,
|
||||||
|
// /organizations/autocomplete uses offset pagination (page/per_page), not cursor pagination.
|
||||||
|
// after_cursor is always null; use next_page URL or page param for subsequent pages.
|
||||||
paging: {
|
paging: {
|
||||||
|
after_cursor: null,
|
||||||
|
has_more: hasMore,
|
||||||
next_page: data.next_page ?? null,
|
next_page: data.next_page ?? null,
|
||||||
previous_page: data.previous_page ?? null,
|
|
||||||
count: data.count || organizations.length,
|
|
||||||
},
|
},
|
||||||
metadata: {
|
metadata: {
|
||||||
total_returned: organizations.length,
|
total_returned: organizations.length,
|
||||||
has_more: !!data.next_page,
|
has_more: hasMore,
|
||||||
},
|
},
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import type { ToolConfig } from '@/tools/types'
|
import type { ToolConfig } from '@/tools/types'
|
||||||
import {
|
import {
|
||||||
|
appendCursorPaginationParams,
|
||||||
buildZendeskUrl,
|
buildZendeskUrl,
|
||||||
|
extractCursorPagingInfo,
|
||||||
handleZendeskError,
|
handleZendeskError,
|
||||||
METADATA_OUTPUT,
|
METADATA_OUTPUT,
|
||||||
ORGANIZATIONS_ARRAY_OUTPUT,
|
ORGANIZATIONS_ARRAY_OUTPUT,
|
||||||
@@ -12,7 +14,7 @@ export interface ZendeskGetOrganizationsParams {
|
|||||||
apiToken: string
|
apiToken: string
|
||||||
subdomain: string
|
subdomain: string
|
||||||
perPage?: string
|
perPage?: string
|
||||||
page?: string
|
pageAfter?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ZendeskGetOrganizationsResponse {
|
export interface ZendeskGetOrganizationsResponse {
|
||||||
@@ -20,9 +22,8 @@ export interface ZendeskGetOrganizationsResponse {
|
|||||||
output: {
|
output: {
|
||||||
organizations: any[]
|
organizations: any[]
|
||||||
paging?: {
|
paging?: {
|
||||||
next_page?: string | null
|
after_cursor: string | null
|
||||||
previous_page?: string | null
|
has_more: boolean
|
||||||
count: number
|
|
||||||
}
|
}
|
||||||
metadata: {
|
metadata: {
|
||||||
total_returned: number
|
total_returned: number
|
||||||
@@ -66,19 +67,18 @@ export const zendeskGetOrganizationsTool: ToolConfig<
|
|||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Results per page as a number string (default: "100", max: "100")',
|
description: 'Results per page as a number string (default: "100", max: "100")',
|
||||||
},
|
},
|
||||||
page: {
|
pageAfter: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: false,
|
required: false,
|
||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Page number as a string (e.g., "1", "2")',
|
description: 'Cursor from a previous response to fetch the next page of results',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
request: {
|
request: {
|
||||||
url: (params) => {
|
url: (params) => {
|
||||||
const queryParams = new URLSearchParams()
|
const queryParams = new URLSearchParams()
|
||||||
if (params.page) queryParams.append('page', params.page)
|
appendCursorPaginationParams(queryParams, params)
|
||||||
if (params.perPage) queryParams.append('per_page', params.perPage)
|
|
||||||
|
|
||||||
const query = queryParams.toString()
|
const query = queryParams.toString()
|
||||||
const url = buildZendeskUrl(params.subdomain, '/organizations')
|
const url = buildZendeskUrl(params.subdomain, '/organizations')
|
||||||
@@ -103,19 +103,16 @@ export const zendeskGetOrganizationsTool: ToolConfig<
|
|||||||
|
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
const organizations = data.organizations || []
|
const organizations = data.organizations || []
|
||||||
|
const paging = extractCursorPagingInfo(data)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
output: {
|
output: {
|
||||||
organizations,
|
organizations,
|
||||||
paging: {
|
paging,
|
||||||
next_page: data.next_page ?? null,
|
|
||||||
previous_page: data.previous_page ?? null,
|
|
||||||
count: data.count || organizations.length,
|
|
||||||
},
|
|
||||||
metadata: {
|
metadata: {
|
||||||
total_returned: organizations.length,
|
total_returned: organizations.length,
|
||||||
has_more: !!data.next_page,
|
has_more: paging.has_more,
|
||||||
},
|
},
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import type { ToolConfig } from '@/tools/types'
|
import type { ToolConfig } from '@/tools/types'
|
||||||
import {
|
import {
|
||||||
|
appendCursorPaginationParams,
|
||||||
buildZendeskUrl,
|
buildZendeskUrl,
|
||||||
|
extractCursorPagingInfo,
|
||||||
handleZendeskError,
|
handleZendeskError,
|
||||||
METADATA_OUTPUT,
|
METADATA_OUTPUT,
|
||||||
PAGING_OUTPUT,
|
PAGING_OUTPUT,
|
||||||
@@ -16,10 +18,9 @@ export interface ZendeskGetTicketsParams {
|
|||||||
type?: string
|
type?: string
|
||||||
assigneeId?: string
|
assigneeId?: string
|
||||||
organizationId?: string
|
organizationId?: string
|
||||||
sortBy?: string
|
sort?: string
|
||||||
sortOrder?: string
|
|
||||||
perPage?: string
|
perPage?: string
|
||||||
page?: string
|
pageAfter?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ZendeskGetTicketsResponse {
|
export interface ZendeskGetTicketsResponse {
|
||||||
@@ -27,9 +28,8 @@ export interface ZendeskGetTicketsResponse {
|
|||||||
output: {
|
output: {
|
||||||
tickets: any[]
|
tickets: any[]
|
||||||
paging?: {
|
paging?: {
|
||||||
next_page?: string | null
|
after_cursor: string | null
|
||||||
previous_page?: string | null
|
has_more: boolean
|
||||||
count: number
|
|
||||||
}
|
}
|
||||||
metadata: {
|
metadata: {
|
||||||
total_returned: number
|
total_returned: number
|
||||||
@@ -95,17 +95,12 @@ export const zendeskGetTicketsTool: ToolConfig<ZendeskGetTicketsParams, ZendeskG
|
|||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Filter by organization ID as a numeric string (e.g., "67890")',
|
description: 'Filter by organization ID as a numeric string (e.g., "67890")',
|
||||||
},
|
},
|
||||||
sortBy: {
|
sort: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: false,
|
required: false,
|
||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Sort field: "created_at", "updated_at", "priority", or "status"',
|
description:
|
||||||
},
|
'Sort field for ticket listing (only applies without filters): "updated_at", "id", or "status". Prefix with "-" for descending (e.g., "-updated_at")',
|
||||||
sortOrder: {
|
|
||||||
type: 'string',
|
|
||||||
required: false,
|
|
||||||
visibility: 'user-or-llm',
|
|
||||||
description: 'Sort order: "asc" or "desc"',
|
|
||||||
},
|
},
|
||||||
perPage: {
|
perPage: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@@ -113,11 +108,11 @@ export const zendeskGetTicketsTool: ToolConfig<ZendeskGetTicketsParams, ZendeskG
|
|||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Results per page as a number string (default: "100", max: "100")',
|
description: 'Results per page as a number string (default: "100", max: "100")',
|
||||||
},
|
},
|
||||||
page: {
|
pageAfter: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: false,
|
required: false,
|
||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Page number as a string (e.g., "1", "2")',
|
description: 'Cursor from a previous response to fetch the next page of results',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -142,20 +137,16 @@ export const zendeskGetTicketsTool: ToolConfig<ZendeskGetTicketsParams, ZendeskG
|
|||||||
|
|
||||||
const queryParams = new URLSearchParams()
|
const queryParams = new URLSearchParams()
|
||||||
queryParams.append('query', searchTerms.join(' '))
|
queryParams.append('query', searchTerms.join(' '))
|
||||||
if (params.sortBy) queryParams.append('sort_by', params.sortBy)
|
queryParams.append('filter[type]', 'ticket')
|
||||||
if (params.sortOrder) queryParams.append('sort_order', params.sortOrder)
|
appendCursorPaginationParams(queryParams, params)
|
||||||
if (params.page) queryParams.append('page', params.page)
|
|
||||||
if (params.perPage) queryParams.append('per_page', params.perPage)
|
|
||||||
|
|
||||||
return `${buildZendeskUrl(params.subdomain, '/search')}?${queryParams.toString()}`
|
return `${buildZendeskUrl(params.subdomain, '/search/export')}?${queryParams.toString()}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// No filters - use the simple /tickets endpoint
|
// No filters - use the simple /tickets endpoint with cursor-based pagination
|
||||||
const queryParams = new URLSearchParams()
|
const queryParams = new URLSearchParams()
|
||||||
if (params.sortBy) queryParams.append('sort_by', params.sortBy)
|
if (params.sort) queryParams.append('sort', params.sort)
|
||||||
if (params.sortOrder) queryParams.append('sort_order', params.sortOrder)
|
appendCursorPaginationParams(queryParams, params)
|
||||||
if (params.page) queryParams.append('page', params.page)
|
|
||||||
if (params.perPage) queryParams.append('per_page', params.perPage)
|
|
||||||
|
|
||||||
const query = queryParams.toString()
|
const query = queryParams.toString()
|
||||||
const url = buildZendeskUrl(params.subdomain, '/tickets')
|
const url = buildZendeskUrl(params.subdomain, '/tickets')
|
||||||
@@ -182,19 +173,16 @@ export const zendeskGetTicketsTool: ToolConfig<ZendeskGetTicketsParams, ZendeskG
|
|||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
// Handle both /tickets response (data.tickets) and /search response (data.results)
|
// Handle both /tickets response (data.tickets) and /search response (data.results)
|
||||||
const tickets = data.tickets || data.results || []
|
const tickets = data.tickets || data.results || []
|
||||||
|
const paging = extractCursorPagingInfo(data)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
output: {
|
output: {
|
||||||
tickets,
|
tickets,
|
||||||
paging: {
|
paging,
|
||||||
next_page: data.next_page ?? null,
|
|
||||||
previous_page: data.previous_page ?? null,
|
|
||||||
count: data.count || tickets.length,
|
|
||||||
},
|
|
||||||
metadata: {
|
metadata: {
|
||||||
total_returned: tickets.length,
|
total_returned: tickets.length,
|
||||||
has_more: !!data.next_page,
|
has_more: paging.has_more,
|
||||||
},
|
},
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import type { ToolConfig } from '@/tools/types'
|
import type { ToolConfig } from '@/tools/types'
|
||||||
import {
|
import {
|
||||||
|
appendCursorPaginationParams,
|
||||||
buildZendeskUrl,
|
buildZendeskUrl,
|
||||||
|
extractCursorPagingInfo,
|
||||||
handleZendeskError,
|
handleZendeskError,
|
||||||
METADATA_OUTPUT,
|
METADATA_OUTPUT,
|
||||||
PAGING_OUTPUT,
|
PAGING_OUTPUT,
|
||||||
@@ -14,7 +16,7 @@ export interface ZendeskGetUsersParams {
|
|||||||
role?: string
|
role?: string
|
||||||
permissionSet?: string
|
permissionSet?: string
|
||||||
perPage?: string
|
perPage?: string
|
||||||
page?: string
|
pageAfter?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ZendeskGetUsersResponse {
|
export interface ZendeskGetUsersResponse {
|
||||||
@@ -22,9 +24,8 @@ export interface ZendeskGetUsersResponse {
|
|||||||
output: {
|
output: {
|
||||||
users: any[]
|
users: any[]
|
||||||
paging?: {
|
paging?: {
|
||||||
next_page?: string | null
|
after_cursor: string | null
|
||||||
previous_page?: string | null
|
has_more: boolean
|
||||||
count: number
|
|
||||||
}
|
}
|
||||||
metadata: {
|
metadata: {
|
||||||
total_returned: number
|
total_returned: number
|
||||||
@@ -77,11 +78,11 @@ export const zendeskGetUsersTool: ToolConfig<ZendeskGetUsersParams, ZendeskGetUs
|
|||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Results per page as a number string (default: "100", max: "100")',
|
description: 'Results per page as a number string (default: "100", max: "100")',
|
||||||
},
|
},
|
||||||
page: {
|
pageAfter: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: false,
|
required: false,
|
||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Page number as a string (e.g., "1", "2")',
|
description: 'Cursor from a previous response to fetch the next page of results',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -90,8 +91,7 @@ export const zendeskGetUsersTool: ToolConfig<ZendeskGetUsersParams, ZendeskGetUs
|
|||||||
const queryParams = new URLSearchParams()
|
const queryParams = new URLSearchParams()
|
||||||
if (params.role) queryParams.append('role', params.role)
|
if (params.role) queryParams.append('role', params.role)
|
||||||
if (params.permissionSet) queryParams.append('permission_set', params.permissionSet)
|
if (params.permissionSet) queryParams.append('permission_set', params.permissionSet)
|
||||||
if (params.page) queryParams.append('page', params.page)
|
appendCursorPaginationParams(queryParams, params)
|
||||||
if (params.perPage) queryParams.append('per_page', params.perPage)
|
|
||||||
|
|
||||||
const query = queryParams.toString()
|
const query = queryParams.toString()
|
||||||
const url = buildZendeskUrl(params.subdomain, '/users')
|
const url = buildZendeskUrl(params.subdomain, '/users')
|
||||||
@@ -116,19 +116,16 @@ export const zendeskGetUsersTool: ToolConfig<ZendeskGetUsersParams, ZendeskGetUs
|
|||||||
|
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
const users = data.users || []
|
const users = data.users || []
|
||||||
|
const paging = extractCursorPagingInfo(data)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
output: {
|
output: {
|
||||||
users,
|
users,
|
||||||
paging: {
|
paging,
|
||||||
next_page: data.next_page ?? null,
|
|
||||||
previous_page: data.previous_page ?? null,
|
|
||||||
count: data.count || users.length,
|
|
||||||
},
|
|
||||||
metadata: {
|
metadata: {
|
||||||
total_returned: users.length,
|
total_returned: users.length,
|
||||||
has_more: !!data.next_page,
|
has_more: paging.has_more,
|
||||||
},
|
},
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import type { ToolConfig } from '@/tools/types'
|
import type { ToolConfig } from '@/tools/types'
|
||||||
import {
|
import {
|
||||||
|
appendCursorPaginationParams,
|
||||||
buildZendeskUrl,
|
buildZendeskUrl,
|
||||||
|
extractCursorPagingInfo,
|
||||||
handleZendeskError,
|
handleZendeskError,
|
||||||
METADATA_OUTPUT,
|
METADATA_OUTPUT,
|
||||||
PAGING_OUTPUT,
|
PAGING_OUTPUT,
|
||||||
@@ -11,10 +13,9 @@ export interface ZendeskSearchParams {
|
|||||||
apiToken: string
|
apiToken: string
|
||||||
subdomain: string
|
subdomain: string
|
||||||
query: string
|
query: string
|
||||||
sortBy?: string
|
filterType: string
|
||||||
sortOrder?: string
|
|
||||||
perPage?: string
|
perPage?: string
|
||||||
page?: string
|
pageAfter?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ZendeskSearchResponse {
|
export interface ZendeskSearchResponse {
|
||||||
@@ -22,9 +23,8 @@ export interface ZendeskSearchResponse {
|
|||||||
output: {
|
output: {
|
||||||
results: any[]
|
results: any[]
|
||||||
paging?: {
|
paging?: {
|
||||||
next_page?: string | null
|
after_cursor: string | null
|
||||||
previous_page?: string | null
|
has_more: boolean
|
||||||
count: number
|
|
||||||
}
|
}
|
||||||
metadata: {
|
metadata: {
|
||||||
total_returned: number
|
total_returned: number
|
||||||
@@ -66,18 +66,11 @@ export const zendeskSearchTool: ToolConfig<ZendeskSearchParams, ZendeskSearchRes
|
|||||||
description:
|
description:
|
||||||
'Search query string using Zendesk search syntax (e.g., "type:ticket status:open")',
|
'Search query string using Zendesk search syntax (e.g., "type:ticket status:open")',
|
||||||
},
|
},
|
||||||
sortBy: {
|
filterType: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: false,
|
required: true,
|
||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description:
|
description: 'Resource type to search for: "ticket", "user", "organization", or "group"',
|
||||||
'Sort field: "relevance", "created_at", "updated_at", "priority", "status", or "ticket_type"',
|
|
||||||
},
|
|
||||||
sortOrder: {
|
|
||||||
type: 'string',
|
|
||||||
required: false,
|
|
||||||
visibility: 'user-or-llm',
|
|
||||||
description: 'Sort order: "asc" or "desc"',
|
|
||||||
},
|
},
|
||||||
perPage: {
|
perPage: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
@@ -85,11 +78,11 @@ export const zendeskSearchTool: ToolConfig<ZendeskSearchParams, ZendeskSearchRes
|
|||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Results per page as a number string (default: "100", max: "100")',
|
description: 'Results per page as a number string (default: "100", max: "100")',
|
||||||
},
|
},
|
||||||
page: {
|
pageAfter: {
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: false,
|
required: false,
|
||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Page number as a string (e.g., "1", "2")',
|
description: 'Cursor from a previous response to fetch the next page of results',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -97,13 +90,11 @@ export const zendeskSearchTool: ToolConfig<ZendeskSearchParams, ZendeskSearchRes
|
|||||||
url: (params) => {
|
url: (params) => {
|
||||||
const queryParams = new URLSearchParams()
|
const queryParams = new URLSearchParams()
|
||||||
queryParams.append('query', params.query)
|
queryParams.append('query', params.query)
|
||||||
if (params.sortBy) queryParams.append('sort_by', params.sortBy)
|
queryParams.append('filter[type]', params.filterType)
|
||||||
if (params.sortOrder) queryParams.append('sort_order', params.sortOrder)
|
appendCursorPaginationParams(queryParams, params)
|
||||||
if (params.page) queryParams.append('page', params.page)
|
|
||||||
if (params.perPage) queryParams.append('per_page', params.perPage)
|
|
||||||
|
|
||||||
const query = queryParams.toString()
|
const query = queryParams.toString()
|
||||||
const url = buildZendeskUrl(params.subdomain, '/search')
|
const url = buildZendeskUrl(params.subdomain, '/search/export')
|
||||||
return `${url}?${query}`
|
return `${url}?${query}`
|
||||||
},
|
},
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
@@ -125,19 +116,16 @@ export const zendeskSearchTool: ToolConfig<ZendeskSearchParams, ZendeskSearchRes
|
|||||||
|
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
const results = data.results || []
|
const results = data.results || []
|
||||||
|
const paging = extractCursorPagingInfo(data)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
output: {
|
output: {
|
||||||
results,
|
results,
|
||||||
paging: {
|
paging,
|
||||||
next_page: data.next_page ?? null,
|
|
||||||
previous_page: data.previous_page ?? null,
|
|
||||||
count: data.count || results.length,
|
|
||||||
},
|
|
||||||
metadata: {
|
metadata: {
|
||||||
total_returned: results.length,
|
total_returned: results.length,
|
||||||
has_more: !!data.next_page,
|
has_more: paging.has_more,
|
||||||
},
|
},
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ export interface ZendeskSearchUsersResponse {
|
|||||||
output: {
|
output: {
|
||||||
users: any[]
|
users: any[]
|
||||||
paging?: {
|
paging?: {
|
||||||
|
after_cursor: string | null
|
||||||
|
has_more: boolean
|
||||||
next_page?: string | null
|
next_page?: string | null
|
||||||
previous_page?: string | null
|
|
||||||
count: number
|
|
||||||
}
|
}
|
||||||
metadata: {
|
metadata: {
|
||||||
total_returned: number
|
total_returned: number
|
||||||
@@ -84,7 +84,7 @@ export const zendeskSearchUsersTool: ToolConfig<
|
|||||||
type: 'string',
|
type: 'string',
|
||||||
required: false,
|
required: false,
|
||||||
visibility: 'user-or-llm',
|
visibility: 'user-or-llm',
|
||||||
description: 'Page number as a string (e.g., "1", "2")',
|
description: 'Page number for pagination (1-based)',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -93,8 +93,8 @@ export const zendeskSearchUsersTool: ToolConfig<
|
|||||||
const queryParams = new URLSearchParams()
|
const queryParams = new URLSearchParams()
|
||||||
if (params.query) queryParams.append('query', params.query)
|
if (params.query) queryParams.append('query', params.query)
|
||||||
if (params.externalId) queryParams.append('external_id', params.externalId)
|
if (params.externalId) queryParams.append('external_id', params.externalId)
|
||||||
if (params.page) queryParams.append('page', params.page)
|
|
||||||
if (params.perPage) queryParams.append('per_page', params.perPage)
|
if (params.perPage) queryParams.append('per_page', params.perPage)
|
||||||
|
if (params.page) queryParams.append('page', params.page)
|
||||||
|
|
||||||
const query = queryParams.toString()
|
const query = queryParams.toString()
|
||||||
const url = buildZendeskUrl(params.subdomain, '/users/search')
|
const url = buildZendeskUrl(params.subdomain, '/users/search')
|
||||||
@@ -119,19 +119,22 @@ export const zendeskSearchUsersTool: ToolConfig<
|
|||||||
|
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
const users = data.users || []
|
const users = data.users || []
|
||||||
|
const hasMore = data.next_page !== null && data.next_page !== undefined
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
output: {
|
output: {
|
||||||
users,
|
users,
|
||||||
|
// /users/search uses offset pagination (page/per_page), not cursor pagination.
|
||||||
|
// after_cursor is always null; use next_page URL or page param for subsequent pages.
|
||||||
paging: {
|
paging: {
|
||||||
|
after_cursor: null,
|
||||||
|
has_more: hasMore,
|
||||||
next_page: data.next_page ?? null,
|
next_page: data.next_page ?? null,
|
||||||
previous_page: data.previous_page ?? null,
|
|
||||||
count: data.count || users.length,
|
|
||||||
},
|
},
|
||||||
metadata: {
|
metadata: {
|
||||||
total_returned: users.length,
|
total_returned: users.length,
|
||||||
has_more: !!data.next_page,
|
has_more: hasMore,
|
||||||
},
|
},
|
||||||
success: true,
|
success: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -11,14 +11,14 @@ export interface ZendeskBaseParams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ZendeskPaginationParams {
|
export interface ZendeskPaginationParams {
|
||||||
page?: string
|
|
||||||
perPage?: string
|
perPage?: string
|
||||||
|
pageAfter?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ZendeskPagingInfo {
|
export interface ZendeskPagingInfo {
|
||||||
|
after_cursor: string | null
|
||||||
|
has_more: boolean
|
||||||
next_page?: string | null
|
next_page?: string | null
|
||||||
previous_page?: string | null
|
|
||||||
count: number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ZendeskListMetadata {
|
export interface ZendeskListMetadata {
|
||||||
@@ -50,6 +50,32 @@ export function handleZendeskError(data: any, status: number, operation: string)
|
|||||||
throw new Error(`Zendesk ${operation} failed: ${errorMessage}`)
|
throw new Error(`Zendesk ${operation} failed: ${errorMessage}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends cursor-based pagination query params.
|
||||||
|
* Zendesk uses bracket notation: `page[size]` and `page[after]`.
|
||||||
|
*/
|
||||||
|
export function appendCursorPaginationParams(
|
||||||
|
queryParams: URLSearchParams,
|
||||||
|
params: ZendeskPaginationParams
|
||||||
|
): void {
|
||||||
|
if (params.perPage) queryParams.append('page[size]', params.perPage)
|
||||||
|
if (params.pageAfter) queryParams.append('page[after]', params.pageAfter)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts cursor-based pagination info from Zendesk API response.
|
||||||
|
* Zendesk cursor-based responses include `meta.after_cursor`, `meta.has_more`, and `links.next`.
|
||||||
|
*/
|
||||||
|
export function extractCursorPagingInfo(data: Record<string, unknown>): ZendeskPagingInfo {
|
||||||
|
const meta = (data.meta as Record<string, unknown>) || {}
|
||||||
|
const links = (data.links as Record<string, unknown>) || {}
|
||||||
|
return {
|
||||||
|
after_cursor: (meta.after_cursor as string) ?? null,
|
||||||
|
has_more: Boolean(meta.has_more),
|
||||||
|
next_page: (links.next as string) ?? null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Output definition for the "via" object in ticket responses.
|
* Output definition for the "via" object in ticket responses.
|
||||||
* Contains information about how the ticket was created.
|
* Contains information about how the ticket was created.
|
||||||
@@ -377,13 +403,13 @@ export const ORGANIZATION_OUTPUT_PROPERTIES = {
|
|||||||
* Pagination output properties for list endpoints
|
* Pagination output properties for list endpoints
|
||||||
*/
|
*/
|
||||||
export const PAGING_OUTPUT_PROPERTIES = {
|
export const PAGING_OUTPUT_PROPERTIES = {
|
||||||
next_page: { type: 'string', description: 'URL for next page of results', optional: true },
|
after_cursor: {
|
||||||
previous_page: {
|
|
||||||
type: 'string',
|
type: 'string',
|
||||||
description: 'URL for previous page of results',
|
description: 'Cursor for fetching the next page of results',
|
||||||
optional: true,
|
optional: true,
|
||||||
},
|
},
|
||||||
count: { type: 'number', description: 'Total count of items' },
|
has_more: { type: 'boolean', description: 'Whether more results are available' },
|
||||||
|
next_page: { type: 'string', description: 'URL for next page of results', optional: true },
|
||||||
} as const satisfies Record<string, OutputProperty>
|
} as const satisfies Record<string, OutputProperty>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -391,7 +417,7 @@ export const PAGING_OUTPUT_PROPERTIES = {
|
|||||||
*/
|
*/
|
||||||
export const PAGING_OUTPUT: OutputProperty = {
|
export const PAGING_OUTPUT: OutputProperty = {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
description: 'Pagination information',
|
description: 'Cursor-based pagination information',
|
||||||
properties: PAGING_OUTPUT_PROPERTIES,
|
properties: PAGING_OUTPUT_PROPERTIES,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
16
bun.lock
16
bun.lock
@@ -13,7 +13,7 @@
|
|||||||
"glob": "13.0.0",
|
"glob": "13.0.0",
|
||||||
"husky": "9.1.7",
|
"husky": "9.1.7",
|
||||||
"lint-staged": "16.0.0",
|
"lint-staged": "16.0.0",
|
||||||
"turbo": "2.8.3",
|
"turbo": "2.8.9",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"apps/docs": {
|
"apps/docs": {
|
||||||
@@ -3437,19 +3437,19 @@
|
|||||||
|
|
||||||
"tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="],
|
"tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="],
|
||||||
|
|
||||||
"turbo": ["turbo@2.8.3", "", { "optionalDependencies": { "turbo-darwin-64": "2.8.3", "turbo-darwin-arm64": "2.8.3", "turbo-linux-64": "2.8.3", "turbo-linux-arm64": "2.8.3", "turbo-windows-64": "2.8.3", "turbo-windows-arm64": "2.8.3" }, "bin": { "turbo": "bin/turbo" } }, "sha512-8Osxz5Tu/Dw2kb31EAY+nhq/YZ3wzmQSmYa1nIArqxgCAldxv9TPlrAiaBUDVnKA4aiPn0OFBD1ACcpc5VFOAQ=="],
|
"turbo": ["turbo@2.8.9", "", { "optionalDependencies": { "turbo-darwin-64": "2.8.9", "turbo-darwin-arm64": "2.8.9", "turbo-linux-64": "2.8.9", "turbo-linux-arm64": "2.8.9", "turbo-windows-64": "2.8.9", "turbo-windows-arm64": "2.8.9" }, "bin": { "turbo": "bin/turbo" } }, "sha512-G+Mq8VVQAlpz/0HTsxiNNk/xywaHGl+dk1oiBREgOEVCCDjXInDlONWUn5srRnC9s5tdHTFD1bx1N19eR4hI+g=="],
|
||||||
|
|
||||||
"turbo-darwin-64": ["turbo-darwin-64@2.8.3", "", { "os": "darwin", "cpu": "x64" }, "sha512-4kXRLfcygLOeNcP6JquqRLmGB/ATjjfehiojL2dJkL7GFm3SPSXbq7oNj8UbD8XriYQ5hPaSuz59iF1ijPHkTw=="],
|
"turbo-darwin-64": ["turbo-darwin-64@2.8.9", "", { "os": "darwin", "cpu": "x64" }, "sha512-KnCw1ZI9KTnEAhdI9avZrnZ/z4wsM++flMA1w8s8PKOqi5daGpFV36qoPafg4S8TmYMe52JPWEoFr0L+lQ5JIw=="],
|
||||||
|
|
||||||
"turbo-darwin-arm64": ["turbo-darwin-arm64@2.8.3", "", { "os": "darwin", "cpu": "arm64" }, "sha512-xF7uCeC0UY0Hrv/tqax0BMbFlVP1J/aRyeGQPZT4NjvIPj8gSPDgFhfkfz06DhUwDg5NgMo04uiSkAWE8WB/QQ=="],
|
"turbo-darwin-arm64": ["turbo-darwin-arm64@2.8.9", "", { "os": "darwin", "cpu": "arm64" }, "sha512-CbD5Y2NKJKBXTOZ7z7Cc7vGlFPZkYjApA7ri9lH4iFwKV1X7MoZswh9gyRLetXYWImVX1BqIvP8KftulJg/wIA=="],
|
||||||
|
|
||||||
"turbo-linux-64": ["turbo-linux-64@2.8.3", "", { "os": "linux", "cpu": "x64" }, "sha512-vxMDXwaOjweW/4etY7BxrXCSkvtwh0PbwVafyfT1Ww659SedUxd5rM3V2ZCmbwG8NiCfY7d6VtxyHx3Wh1GoZA=="],
|
"turbo-linux-64": ["turbo-linux-64@2.8.9", "", { "os": "linux", "cpu": "x64" }, "sha512-OXC9HdCtsHvyH+5KUoH8ds+p5WU13vdif0OPbsFzZca4cUXMwKA3HWwUuCgQetk0iAE4cscXpi/t8A263n3VTg=="],
|
||||||
|
|
||||||
"turbo-linux-arm64": ["turbo-linux-arm64@2.8.3", "", { "os": "linux", "cpu": "arm64" }, "sha512-mQX7uYBZFkuPLLlKaNe9IjR1JIef4YvY8f21xFocvttXvdPebnq3PK1Zjzl9A1zun2BEuWNUwQIL8lgvN9Pm3Q=="],
|
"turbo-linux-arm64": ["turbo-linux-arm64@2.8.9", "", { "os": "linux", "cpu": "arm64" }, "sha512-yI5n8jNXiFA6+CxnXG0gO7h5ZF1+19K8uO3/kXPQmyl37AdiA7ehKJQOvf9OPAnmkGDHcF2HSCPltabERNRmug=="],
|
||||||
|
|
||||||
"turbo-windows-64": ["turbo-windows-64@2.8.3", "", { "os": "win32", "cpu": "x64" }, "sha512-YLGEfppGxZj3VWcNOVa08h6ISsVKiG85aCAWosOKNUjb6yErWEuydv6/qImRJUI+tDLvDvW7BxopAkujRnWCrw=="],
|
"turbo-windows-64": ["turbo-windows-64@2.8.9", "", { "os": "win32", "cpu": "x64" }, "sha512-/OztzeGftJAg258M/9vK2ZCkUKUzqrWXJIikiD2pm8TlqHcIYUmepDbyZSDfOiUjMy6NzrLFahpNLnY7b5vNgg=="],
|
||||||
|
|
||||||
"turbo-windows-arm64": ["turbo-windows-arm64@2.8.3", "", { "os": "win32", "cpu": "arm64" }, "sha512-afTUGKBRmOJU1smQSBnFGcbq0iabAPwh1uXu2BVk7BREg30/1gMnJh9DFEQTah+UD3n3ru8V55J83RQNFfqoyw=="],
|
"turbo-windows-arm64": ["turbo-windows-arm64@2.8.9", "", { "os": "win32", "cpu": "arm64" }, "sha512-xZ2VTwVTjIqpFZKN4UBxDHCPM3oJ2J5cpRzCBSmRpJ/Pn33wpiYjs+9FB2E03svKaD04/lSSLlEUej0UYsugfg=="],
|
||||||
|
|
||||||
"tweetnacl": ["tweetnacl@0.14.5", "", {}, "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="],
|
"tweetnacl": ["tweetnacl@0.14.5", "", {}, "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="],
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@
|
|||||||
"glob": "13.0.0",
|
"glob": "13.0.0",
|
||||||
"husky": "9.1.7",
|
"husky": "9.1.7",
|
||||||
"lint-staged": "16.0.0",
|
"lint-staged": "16.0.0",
|
||||||
"turbo": "2.8.3"
|
"turbo": "2.8.9"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*.{js,jsx,ts,tsx,json,css,scss}": [
|
"*.{js,jsx,ts,tsx,json,css,scss}": [
|
||||||
|
|||||||
Reference in New Issue
Block a user