From d12f1c3783ceff272a74565986282c2c5b990b07 Mon Sep 17 00:00:00 2001 From: waleed Date: Thu, 11 Jun 2026 17:47:00 -0700 Subject: [PATCH 1/2] feat(integrations): add Quartr integration with company, event, document, audio, and live event tools --- apps/docs/components/icons.tsx | 44 ++ apps/docs/components/ui/icon-mapping.ts | 2 + .../content/docs/en/integrations/meta.json | 1 + .../content/docs/en/integrations/quartr.mdx | 687 ++++++++++++++++++ apps/sim/blocks/blocks/quartr.ts | 644 ++++++++++++++++ apps/sim/blocks/registry.ts | 3 + apps/sim/components/icons.tsx | 44 ++ apps/sim/lib/integrations/icon-mapping.ts | 2 + apps/sim/lib/integrations/integrations.json | 87 +++ apps/sim/tools/quartr/get_audio.ts | 60 ++ apps/sim/tools/quartr/get_company.ts | 60 ++ apps/sim/tools/quartr/get_event.ts | 56 ++ apps/sim/tools/quartr/get_event_summary.ts | 97 +++ apps/sim/tools/quartr/get_report.ts | 77 ++ apps/sim/tools/quartr/get_slide_deck.ts | 79 ++ apps/sim/tools/quartr/get_transcript.ts | 80 ++ apps/sim/tools/quartr/index.ts | 17 + apps/sim/tools/quartr/list_audio.ts | 165 +++++ apps/sim/tools/quartr/list_companies.ts | 148 ++++ apps/sim/tools/quartr/list_document_types.ts | 86 +++ apps/sim/tools/quartr/list_documents.ts | 174 +++++ apps/sim/tools/quartr/list_event_types.ts | 86 +++ apps/sim/tools/quartr/list_events.ts | 165 +++++ apps/sim/tools/quartr/list_live_events.ts | 176 +++++ apps/sim/tools/quartr/list_reports.ts | 174 +++++ apps/sim/tools/quartr/list_slide_decks.ts | 174 +++++ apps/sim/tools/quartr/list_transcripts.ts | 174 +++++ apps/sim/tools/quartr/types.ts | 675 +++++++++++++++++ apps/sim/tools/quartr/utils.ts | 259 +++++++ apps/sim/tools/registry.ts | 36 + 30 files changed, 4532 insertions(+) create mode 100644 apps/docs/content/docs/en/integrations/quartr.mdx create mode 100644 apps/sim/blocks/blocks/quartr.ts create mode 100644 apps/sim/tools/quartr/get_audio.ts create mode 100644 apps/sim/tools/quartr/get_company.ts create mode 100644 apps/sim/tools/quartr/get_event.ts create mode 100644 apps/sim/tools/quartr/get_event_summary.ts create mode 100644 apps/sim/tools/quartr/get_report.ts create mode 100644 apps/sim/tools/quartr/get_slide_deck.ts create mode 100644 apps/sim/tools/quartr/get_transcript.ts create mode 100644 apps/sim/tools/quartr/index.ts create mode 100644 apps/sim/tools/quartr/list_audio.ts create mode 100644 apps/sim/tools/quartr/list_companies.ts create mode 100644 apps/sim/tools/quartr/list_document_types.ts create mode 100644 apps/sim/tools/quartr/list_documents.ts create mode 100644 apps/sim/tools/quartr/list_event_types.ts create mode 100644 apps/sim/tools/quartr/list_events.ts create mode 100644 apps/sim/tools/quartr/list_live_events.ts create mode 100644 apps/sim/tools/quartr/list_reports.ts create mode 100644 apps/sim/tools/quartr/list_slide_decks.ts create mode 100644 apps/sim/tools/quartr/list_transcripts.ts create mode 100644 apps/sim/tools/quartr/types.ts create mode 100644 apps/sim/tools/quartr/utils.ts diff --git a/apps/docs/components/icons.tsx b/apps/docs/components/icons.tsx index ae3f48d4c0..2dd06da0b5 100644 --- a/apps/docs/components/icons.tsx +++ b/apps/docs/components/icons.tsx @@ -3705,6 +3705,50 @@ export function QdrantIcon(props: SVGProps) { ) } +export function QuartrIcon(props: SVGProps) { + return ( + + + + + + + + + + + + + ) +} + export function QuiverIcon(props: SVGProps) { return ( = { pulse: PulseIcon, pulse_v2: PulseIcon, qdrant: QdrantIcon, + quartr: QuartrIcon, quiver: QuiverIcon, railway: RailwayIcon, rb2b: RB2BIcon, diff --git a/apps/docs/content/docs/en/integrations/meta.json b/apps/docs/content/docs/en/integrations/meta.json index dc420998f8..ca880ca7bb 100644 --- a/apps/docs/content/docs/en/integrations/meta.json +++ b/apps/docs/content/docs/en/integrations/meta.json @@ -158,6 +158,7 @@ "prospeo", "pulse", "qdrant", + "quartr", "quiver", "railway", "rb2b", diff --git a/apps/docs/content/docs/en/integrations/quartr.mdx b/apps/docs/content/docs/en/integrations/quartr.mdx new file mode 100644 index 0000000000..bdc71b0926 --- /dev/null +++ b/apps/docs/content/docs/en/integrations/quartr.mdx @@ -0,0 +1,687 @@ +--- +title: Quartr +description: Access earnings calls, transcripts, filings, and slides +--- + +import { BlockInfoCard } from "@/components/ui/block-info-card" + + + +{/* MANUAL-CONTENT-START:intro */} +[Quartr](https://quartr.com/) is an investor relations data platform that provides structured, AI-ready access to live and historical earnings data from more than 15,000 public companies across 65+ markets. It covers earnings calls, transcripts, filings, reports, slide presentations, and AI-generated event summaries. + +With the Quartr integration in Sim, you can: + +- **Look up companies**: Find any covered public company by ticker, ISIN, CIK, OpenFIGI, country, or exchange, and resolve it to a Quartr company ID. +- **Track corporate events**: List earnings calls and other corporate events by company, event type, and date range, or retrieve a single event with its fiscal period details. +- **Summarize earnings calls**: Fetch AI-generated event summaries in one-line, short, or long form — with source references back to the underlying documents. +- **Download filings and reports**: List 10-Ks, 10-Qs, earnings releases, and other filings, and download report PDFs directly into your workflow as files. +- **Work with slide decks and transcripts**: Retrieve investor presentation PDFs and structured transcript JSON files (with timestamps and speaker identification) for downstream analysis. +- **Access event audio**: Get download and streaming URLs for archived earnings call audio, including where the Q&A section starts. +- **Monitor live events**: List live and upcoming events with their live audio and transcript stream URLs to react the moment a company goes live. + +Downloaded reports, slide decks, and transcripts are stored as execution files, so they can be passed straight into agents, knowledge bases, or other blocks in your workflow. + +To use the integration, generate an API key from the Quartr API portal and paste it into the block. Your key inherits the datasets enabled on your Quartr subscription. +{/* MANUAL-CONTENT-END */} + + +## Usage Instructions + +Integrate Quartr into the workflow. Look up public companies, corporate events, and event types; fetch AI-generated event summaries; list and download filings, reports, slide decks, and transcripts; and access archived audio and live event streams. Requires API Key. + + + +## Actions + +### `quartr_list_companies` + +List companies covered by Quartr, filterable by ticker, ISIN, CIK, OpenFIGI, country, and exchange. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Quartr API key | +| `tickers` | string | No | Comma-separated list of company tickers \(e.g., "AAPL,MSFT"\) | +| `isins` | string | No | Comma-separated list of ISINs \(e.g., "US0378331005"\) | +| `ciks` | string | No | Comma-separated list of SEC CIKs \(e.g., "0000320193"\) | +| `countries` | string | No | Comma-separated list of ISO 3166-1 alpha-2 country codes \(e.g., "US,SE"\) | +| `exchanges` | string | No | Comma-separated list of exchange symbols, without whitespace \(e.g., "NasdaqGS"\) | +| `companyIds` | string | No | Comma-separated list of Quartr company IDs \(e.g., "4742,128"\) | +| `openfigis` | string | No | Comma-separated list of OpenFIGI codes \(figi, compositeFigi, or shareClassFigi\) | +| `updatedAfter` | string | No | Only return data updated after this ISO 8601 date \(e.g., "2024-01-01"\) | +| `updatedBefore` | string | No | Only return data updated before this ISO 8601 date \(e.g., "2024-12-31"\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | +| `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `companies` | array | Companies matching the filters | +| ↳ `id` | number | Quartr company ID | +| ↳ `name` | string | Legal company name | +| ↳ `displayName` | string | Display name | +| ↳ `country` | string | ISO 3166-1 alpha-2 country code | +| ↳ `tickers` | array | Ticker listings for the company | +| ↳ `ticker` | string | Ticker symbol | +| ↳ `exchange` | string | Exchange symbol | +| ↳ `isins` | array | ISINs for the company | +| ↳ `cik` | string | SEC Central Index Key | +| ↳ `openfigi` | array | OpenFIGI share class identifiers | +| ↳ `backlinkUrl` | string | Quartr backlink URL for the company | +| ↳ `createdAt` | string | Creation timestamp \(ISO 8601\) | +| ↳ `updatedAt` | string | Last update timestamp \(ISO 8601\) | +| `nextCursor` | number | Cursor for fetching the next page of results \(null when no more pages\) | + +### `quartr_get_company` + +Retrieve a single company from Quartr by its company ID. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Quartr API key | +| `companyId` | number | Yes | Quartr company ID \(e.g., 4742\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `company` | object | The requested company | +| ↳ `id` | number | Quartr company ID | +| ↳ `name` | string | Legal company name | +| ↳ `displayName` | string | Display name | +| ↳ `country` | string | ISO 3166-1 alpha-2 country code | +| ↳ `tickers` | array | Ticker listings for the company | +| ↳ `ticker` | string | Ticker symbol | +| ↳ `exchange` | string | Exchange symbol | +| ↳ `isins` | array | ISINs for the company | +| ↳ `cik` | string | SEC Central Index Key | +| ↳ `openfigi` | array | OpenFIGI share class identifiers | +| ↳ `backlinkUrl` | string | Quartr backlink URL for the company | +| ↳ `createdAt` | string | Creation timestamp \(ISO 8601\) | +| ↳ `updatedAt` | string | Last update timestamp \(ISO 8601\) | + +### `quartr_list_events` + +List corporate events (earnings calls, capital markets days, etc.) from Quartr, filterable by company, event type, and date range. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Quartr API key | +| `companyIds` | string | No | Comma-separated list of Quartr company IDs \(e.g., "4742,128"\) | +| `tickers` | string | No | Comma-separated list of company tickers \(e.g., "AAPL,MSFT"\) | +| `isins` | string | No | Comma-separated list of ISINs \(e.g., "US0378331005"\) | +| `ciks` | string | No | Comma-separated list of SEC CIKs \(e.g., "0000320193"\) | +| `countries` | string | No | Comma-separated list of ISO 3166-1 alpha-2 country codes \(e.g., "US,SE"\) | +| `exchanges` | string | No | Comma-separated list of exchange symbols, without whitespace \(e.g., "NasdaqGS"\) | +| `eventTypeIds` | string | No | Comma-separated list of event type IDs \(e.g., "26,27"\) | +| `startDate` | string | No | Only return events on or after this ISO 8601 date \(e.g., "2024-01-01"\) | +| `endDate` | string | No | Only return events on or before this ISO 8601 date \(e.g., "2024-12-31"\) | +| `sortBy` | string | No | Field to sort by: "id" or "date" \(default: id\) | +| `updatedAfter` | string | No | Only return data updated after this ISO 8601 date \(e.g., "2024-01-01"\) | +| `updatedBefore` | string | No | Only return data updated before this ISO 8601 date \(e.g., "2024-12-31"\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | +| `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `events` | array | Events matching the filters | +| ↳ `id` | number | Quartr event ID | +| ↳ `companyId` | number | Quartr company ID | +| ↳ `title` | string | Event title \(e.g., "Q1 2024"\) | +| ↳ `date` | string | Event date \(ISO 8601\) | +| ↳ `typeId` | number | Event type ID | +| ↳ `fiscalYear` | number | Fiscal year | +| ↳ `fiscalPeriod` | string | Fiscal period \(e.g., "Q1"\) | +| ↳ `language` | string | Event language code | +| ↳ `backlinkUrl` | string | Quartr backlink URL for the event | +| ↳ `createdAt` | string | Creation timestamp \(ISO 8601\) | +| ↳ `updatedAt` | string | Last update timestamp \(ISO 8601\) | +| `nextCursor` | number | Cursor for fetching the next page of results \(null when no more pages\) | + +### `quartr_get_event` + +Retrieve a single corporate event from Quartr by its event ID. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Quartr API key | +| `eventId` | number | Yes | Quartr event ID \(e.g., 128301\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `event` | object | The requested event | +| ↳ `id` | number | Quartr event ID | +| ↳ `companyId` | number | Quartr company ID | +| ↳ `title` | string | Event title \(e.g., "Q1 2024"\) | +| ↳ `date` | string | Event date \(ISO 8601\) | +| ↳ `typeId` | number | Event type ID | +| ↳ `fiscalYear` | number | Fiscal year | +| ↳ `fiscalPeriod` | string | Fiscal period \(e.g., "Q1"\) | +| ↳ `language` | string | Event language code | +| ↳ `backlinkUrl` | string | Quartr backlink URL for the event | +| ↳ `createdAt` | string | Creation timestamp \(ISO 8601\) | +| ↳ `updatedAt` | string | Last update timestamp \(ISO 8601\) | + +### `quartr_get_event_summary` + +Retrieve the AI-generated summary of a corporate event from Quartr, with selectable length and optional plain-text formatting. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Quartr API key | +| `eventId` | number | Yes | Quartr event ID \(e.g., 128301\) | +| `summaryLength` | string | No | Length preset for the summary: "line", "short", or "long" \(default: short\) | +| `plainSummary` | boolean | No | Return a plain-text summary without embedded document source tags | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `summary` | string | AI-generated event summary in Markdown | +| `sources` | array | Source documents referenced by the summary | +| ↳ `sourceId` | string | ID linking the source document to tags embedded in the summary | +| ↳ `documentId` | number | Quartr document ID of the source | +| ↳ `page` | number | Page number or timestamp in seconds depending on the document type | +| ↳ `timestamp` | number | Timestamp in seconds | +| ↳ `typeId` | number | Document type ID of the source | +| `summaryId` | number | Quartr summary ID | +| `summaryCreatedAt` | string | Summary creation timestamp \(ISO 8601\) | +| `summaryUpdatedAt` | string | Summary last update timestamp \(ISO 8601\) | + +### `quartr_list_event_types` + +List the event types available in Quartr (e.g., earnings calls), useful for filtering events by type ID. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Quartr API key | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | +| `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `eventTypes` | array | Available event types | +| ↳ `id` | number | Event type ID | +| ↳ `name` | string | Event type name \(e.g., "Q1"\) | +| ↳ `parent` | string | Parent event type name \(e.g., "Earnings call"\) | +| ↳ `createdAt` | string | Creation timestamp \(ISO 8601\) | +| ↳ `updatedAt` | string | Last update timestamp \(ISO 8601\) | +| `nextCursor` | number | Cursor for fetching the next page of results \(null when no more pages\) | + +### `quartr_list_documents` + +List documents of all kinds (reports, slide decks, and transcripts) from Quartr, filterable by company, event, document type, document group, and date range. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Quartr API key | +| `companyIds` | string | No | Comma-separated list of Quartr company IDs \(e.g., "4742,128"\) | +| `eventIds` | string | No | Comma-separated list of Quartr event IDs \(e.g., "128301"\) | +| `tickers` | string | No | Comma-separated list of company tickers \(e.g., "AAPL,MSFT"\) | +| `isins` | string | No | Comma-separated list of ISINs \(e.g., "US0378331005"\) | +| `ciks` | string | No | Comma-separated list of SEC CIKs \(e.g., "0000320193"\) | +| `countries` | string | No | Comma-separated list of ISO 3166-1 alpha-2 country codes \(e.g., "US,SE"\) | +| `exchanges` | string | No | Comma-separated list of exchange symbols, without whitespace \(e.g., "NasdaqGS"\) | +| `documentTypeIds` | string | No | Comma-separated list of document type IDs \(e.g., "7,10"\) | +| `documentGroupIds` | string | No | Comma-separated list of document group IDs: 1 = Earnings Release, 2 = Press Release, 3 = Interim Report, 4 = Annual Report, 5 = Proxy Statement, 6 = Registration Statement | +| `startDate` | string | No | Only return documents dated on or after this ISO 8601 date \(e.g., "2024-01-01"\) | +| `endDate` | string | No | Only return documents dated on or before this ISO 8601 date \(e.g., "2024-12-31"\) | +| `expandEvent` | boolean | No | Include expanded event details on each document | +| `updatedAfter` | string | No | Only return data updated after this ISO 8601 date \(e.g., "2024-01-01"\) | +| `updatedBefore` | string | No | Only return data updated before this ISO 8601 date \(e.g., "2024-12-31"\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | +| `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `documents` | array | Documents matching the filters | +| ↳ `id` | number | Quartr document ID | +| ↳ `companyId` | number | Quartr company ID | +| ↳ `eventId` | number | Quartr event ID | +| ↳ `typeId` | number | Document type ID | +| ↳ `fileUrl` | string | URL of the document file | +| ↳ `createdAt` | string | Creation timestamp \(ISO 8601\) | +| ↳ `updatedAt` | string | Last update timestamp \(ISO 8601\) | +| ↳ `event` | object | Expanded event details \(present when event expansion is requested\) | +| ↳ `title` | string | Event title | +| ↳ `typeId` | number | Event type ID | +| ↳ `fiscalYear` | number | Fiscal year | +| ↳ `fiscalPeriod` | string | Fiscal period \(e.g., "Q1"\) | +| ↳ `language` | string | Event language code | +| ↳ `date` | string | Event date \(ISO 8601\) | +| `nextCursor` | number | Cursor for fetching the next page of results \(null when no more pages\) | + +### `quartr_list_document_types` + +List the document types available in Quartr (e.g., 10-Q quarterly reports), useful for filtering documents by type ID. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Quartr API key | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | +| `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `documentTypes` | array | Available document types | +| ↳ `id` | number | Document type ID | +| ↳ `name` | string | Document type name \(e.g., "Quarterly Report"\) | +| ↳ `description` | string | Document type description | +| ↳ `form` | string | Filing form \(e.g., "10-Q"\) | +| ↳ `category` | string | Document category \(e.g., "Report"\) | +| ↳ `documentGroupId` | number | Document group ID | +| ↳ `createdAt` | string | Creation timestamp \(ISO 8601\) | +| ↳ `updatedAt` | string | Last update timestamp \(ISO 8601\) | +| `nextCursor` | number | Cursor for fetching the next page of results \(null when no more pages\) | + +### `quartr_list_reports` + +List filings and reports (10-K, 10-Q, earnings releases, etc.) from Quartr, filterable by company, event, document type, document group, and date range. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Quartr API key | +| `companyIds` | string | No | Comma-separated list of Quartr company IDs \(e.g., "4742,128"\) | +| `eventIds` | string | No | Comma-separated list of Quartr event IDs \(e.g., "128301"\) | +| `tickers` | string | No | Comma-separated list of company tickers \(e.g., "AAPL,MSFT"\) | +| `isins` | string | No | Comma-separated list of ISINs \(e.g., "US0378331005"\) | +| `ciks` | string | No | Comma-separated list of SEC CIKs \(e.g., "0000320193"\) | +| `countries` | string | No | Comma-separated list of ISO 3166-1 alpha-2 country codes \(e.g., "US,SE"\) | +| `exchanges` | string | No | Comma-separated list of exchange symbols, without whitespace \(e.g., "NasdaqGS"\) | +| `documentTypeIds` | string | No | Comma-separated list of document type IDs \(e.g., "7,10"\) | +| `documentGroupIds` | string | No | Comma-separated list of document group IDs: 1 = Earnings Release, 2 = Press Release, 3 = Interim Report, 4 = Annual Report, 5 = Proxy Statement, 6 = Registration Statement | +| `startDate` | string | No | Only return documents dated on or after this ISO 8601 date \(e.g., "2024-01-01"\) | +| `endDate` | string | No | Only return documents dated on or before this ISO 8601 date \(e.g., "2024-12-31"\) | +| `expandEvent` | boolean | No | Include expanded event details on each document | +| `updatedAfter` | string | No | Only return data updated after this ISO 8601 date \(e.g., "2024-01-01"\) | +| `updatedBefore` | string | No | Only return data updated before this ISO 8601 date \(e.g., "2024-12-31"\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | +| `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `reports` | array | Reports matching the filters | +| ↳ `id` | number | Quartr document ID | +| ↳ `companyId` | number | Quartr company ID | +| ↳ `eventId` | number | Quartr event ID | +| ↳ `typeId` | number | Document type ID | +| ↳ `fileUrl` | string | URL of the document file | +| ↳ `createdAt` | string | Creation timestamp \(ISO 8601\) | +| ↳ `updatedAt` | string | Last update timestamp \(ISO 8601\) | +| ↳ `event` | object | Expanded event details \(present when event expansion is requested\) | +| ↳ `title` | string | Event title | +| ↳ `typeId` | number | Event type ID | +| ↳ `fiscalYear` | number | Fiscal year | +| ↳ `fiscalPeriod` | string | Fiscal period \(e.g., "Q1"\) | +| ↳ `language` | string | Event language code | +| ↳ `date` | string | Event date \(ISO 8601\) | +| `nextCursor` | number | Cursor for fetching the next page of results \(null when no more pages\) | + +### `quartr_get_report` + +Retrieve a filing or report (10-K, 10-Q, earnings release, etc.) from Quartr by its document ID and download the PDF file. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Quartr API key | +| `reportId` | number | Yes | Quartr document ID of the report \(e.g., 432907\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `document` | object | Report metadata | +| ↳ `id` | number | Quartr document ID | +| ↳ `companyId` | number | Quartr company ID | +| ↳ `eventId` | number | Quartr event ID | +| ↳ `typeId` | number | Document type ID | +| ↳ `fileUrl` | string | URL of the document file | +| ↳ `createdAt` | string | Creation timestamp \(ISO 8601\) | +| ↳ `updatedAt` | string | Last update timestamp \(ISO 8601\) | +| ↳ `event` | object | Expanded event details \(present when event expansion is requested\) | +| ↳ `title` | string | Event title | +| ↳ `typeId` | number | Event type ID | +| ↳ `fiscalYear` | number | Fiscal year | +| ↳ `fiscalPeriod` | string | Fiscal period \(e.g., "Q1"\) | +| ↳ `language` | string | Event language code | +| ↳ `date` | string | Event date \(ISO 8601\) | +| `fileUrl` | string | URL of the report PDF | +| `file` | file | Downloaded report PDF stored in execution files | + +### `quartr_list_slide_decks` + +List slide presentations from Quartr, filterable by company, event, document type, document group, and date range. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Quartr API key | +| `companyIds` | string | No | Comma-separated list of Quartr company IDs \(e.g., "4742,128"\) | +| `eventIds` | string | No | Comma-separated list of Quartr event IDs \(e.g., "128301"\) | +| `tickers` | string | No | Comma-separated list of company tickers \(e.g., "AAPL,MSFT"\) | +| `isins` | string | No | Comma-separated list of ISINs \(e.g., "US0378331005"\) | +| `ciks` | string | No | Comma-separated list of SEC CIKs \(e.g., "0000320193"\) | +| `countries` | string | No | Comma-separated list of ISO 3166-1 alpha-2 country codes \(e.g., "US,SE"\) | +| `exchanges` | string | No | Comma-separated list of exchange symbols, without whitespace \(e.g., "NasdaqGS"\) | +| `documentTypeIds` | string | No | Comma-separated list of document type IDs \(e.g., "7,10"\) | +| `documentGroupIds` | string | No | Comma-separated list of document group IDs: 1 = Earnings Release, 2 = Press Release, 3 = Interim Report, 4 = Annual Report, 5 = Proxy Statement, 6 = Registration Statement | +| `startDate` | string | No | Only return documents dated on or after this ISO 8601 date \(e.g., "2024-01-01"\) | +| `endDate` | string | No | Only return documents dated on or before this ISO 8601 date \(e.g., "2024-12-31"\) | +| `expandEvent` | boolean | No | Include expanded event details on each document | +| `updatedAfter` | string | No | Only return data updated after this ISO 8601 date \(e.g., "2024-01-01"\) | +| `updatedBefore` | string | No | Only return data updated before this ISO 8601 date \(e.g., "2024-12-31"\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | +| `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `slideDecks` | array | Slide decks matching the filters | +| ↳ `id` | number | Quartr document ID | +| ↳ `companyId` | number | Quartr company ID | +| ↳ `eventId` | number | Quartr event ID | +| ↳ `typeId` | number | Document type ID | +| ↳ `fileUrl` | string | URL of the document file | +| ↳ `createdAt` | string | Creation timestamp \(ISO 8601\) | +| ↳ `updatedAt` | string | Last update timestamp \(ISO 8601\) | +| ↳ `event` | object | Expanded event details \(present when event expansion is requested\) | +| ↳ `title` | string | Event title | +| ↳ `typeId` | number | Event type ID | +| ↳ `fiscalYear` | number | Fiscal year | +| ↳ `fiscalPeriod` | string | Fiscal period \(e.g., "Q1"\) | +| ↳ `language` | string | Event language code | +| ↳ `date` | string | Event date \(ISO 8601\) | +| `nextCursor` | number | Cursor for fetching the next page of results \(null when no more pages\) | + +### `quartr_get_slide_deck` + +Retrieve a slide presentation from Quartr by its document ID and download the PDF file. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Quartr API key | +| `slideDeckId` | number | Yes | Quartr document ID of the slide deck \(e.g., 432907\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `document` | object | Slide deck metadata | +| ↳ `id` | number | Quartr document ID | +| ↳ `companyId` | number | Quartr company ID | +| ↳ `eventId` | number | Quartr event ID | +| ↳ `typeId` | number | Document type ID | +| ↳ `fileUrl` | string | URL of the document file | +| ↳ `createdAt` | string | Creation timestamp \(ISO 8601\) | +| ↳ `updatedAt` | string | Last update timestamp \(ISO 8601\) | +| ↳ `event` | object | Expanded event details \(present when event expansion is requested\) | +| ↳ `title` | string | Event title | +| ↳ `typeId` | number | Event type ID | +| ↳ `fiscalYear` | number | Fiscal year | +| ↳ `fiscalPeriod` | string | Fiscal period \(e.g., "Q1"\) | +| ↳ `language` | string | Event language code | +| ↳ `date` | string | Event date \(ISO 8601\) | +| `fileUrl` | string | URL of the slide deck PDF | +| `file` | file | Downloaded slide deck PDF stored in execution files | + +### `quartr_list_transcripts` + +List event transcripts from Quartr, filterable by company, event, document type, document group, and date range. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Quartr API key | +| `companyIds` | string | No | Comma-separated list of Quartr company IDs \(e.g., "4742,128"\) | +| `eventIds` | string | No | Comma-separated list of Quartr event IDs \(e.g., "128301"\) | +| `tickers` | string | No | Comma-separated list of company tickers \(e.g., "AAPL,MSFT"\) | +| `isins` | string | No | Comma-separated list of ISINs \(e.g., "US0378331005"\) | +| `ciks` | string | No | Comma-separated list of SEC CIKs \(e.g., "0000320193"\) | +| `countries` | string | No | Comma-separated list of ISO 3166-1 alpha-2 country codes \(e.g., "US,SE"\) | +| `exchanges` | string | No | Comma-separated list of exchange symbols, without whitespace \(e.g., "NasdaqGS"\) | +| `documentTypeIds` | string | No | Comma-separated list of document type IDs \(e.g., "7,10"\) | +| `documentGroupIds` | string | No | Comma-separated list of document group IDs: 1 = Earnings Release, 2 = Press Release, 3 = Interim Report, 4 = Annual Report, 5 = Proxy Statement, 6 = Registration Statement | +| `startDate` | string | No | Only return documents dated on or after this ISO 8601 date \(e.g., "2024-01-01"\) | +| `endDate` | string | No | Only return documents dated on or before this ISO 8601 date \(e.g., "2024-12-31"\) | +| `expandEvent` | boolean | No | Include expanded event details on each document | +| `updatedAfter` | string | No | Only return data updated after this ISO 8601 date \(e.g., "2024-01-01"\) | +| `updatedBefore` | string | No | Only return data updated before this ISO 8601 date \(e.g., "2024-12-31"\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | +| `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `transcripts` | array | Transcripts matching the filters | +| ↳ `id` | number | Quartr document ID | +| ↳ `companyId` | number | Quartr company ID | +| ↳ `eventId` | number | Quartr event ID | +| ↳ `typeId` | number | Document type ID | +| ↳ `fileUrl` | string | URL of the document file | +| ↳ `createdAt` | string | Creation timestamp \(ISO 8601\) | +| ↳ `updatedAt` | string | Last update timestamp \(ISO 8601\) | +| ↳ `event` | object | Expanded event details \(present when event expansion is requested\) | +| ↳ `title` | string | Event title | +| ↳ `typeId` | number | Event type ID | +| ↳ `fiscalYear` | number | Fiscal year | +| ↳ `fiscalPeriod` | string | Fiscal period \(e.g., "Q1"\) | +| ↳ `language` | string | Event language code | +| ↳ `date` | string | Event date \(ISO 8601\) | +| `nextCursor` | number | Cursor for fetching the next page of results \(null when no more pages\) | + +### `quartr_get_transcript` + +Retrieve an event transcript from Quartr by its document ID and download the transcript JSON file (paragraphs, sentences, timestamps, and speaker identification). + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Quartr API key | +| `transcriptId` | number | Yes | Quartr document ID of the transcript \(e.g., 432907\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `document` | object | Transcript metadata | +| ↳ `id` | number | Quartr document ID | +| ↳ `companyId` | number | Quartr company ID | +| ↳ `eventId` | number | Quartr event ID | +| ↳ `typeId` | number | Document type ID | +| ↳ `fileUrl` | string | URL of the document file | +| ↳ `createdAt` | string | Creation timestamp \(ISO 8601\) | +| ↳ `updatedAt` | string | Last update timestamp \(ISO 8601\) | +| ↳ `event` | object | Expanded event details \(present when event expansion is requested\) | +| ↳ `title` | string | Event title | +| ↳ `typeId` | number | Event type ID | +| ↳ `fiscalYear` | number | Fiscal year | +| ↳ `fiscalPeriod` | string | Fiscal period \(e.g., "Q1"\) | +| ↳ `language` | string | Event language code | +| ↳ `date` | string | Event date \(ISO 8601\) | +| `fileUrl` | string | URL of the transcript JSON file | +| `file` | file | Downloaded transcript JSON file stored in execution files | + +### `quartr_list_audio` + +List archived event audio recordings from Quartr, filterable by company, event, and date range. Returns download (MPEG) and streaming (M3U8) URLs. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Quartr API key | +| `companyIds` | string | No | Comma-separated list of Quartr company IDs \(e.g., "4742,128"\) | +| `eventIds` | string | No | Comma-separated list of Quartr event IDs \(e.g., "128301"\) | +| `tickers` | string | No | Comma-separated list of company tickers \(e.g., "AAPL,MSFT"\) | +| `isins` | string | No | Comma-separated list of ISINs \(e.g., "US0378331005"\) | +| `ciks` | string | No | Comma-separated list of SEC CIKs \(e.g., "0000320193"\) | +| `countries` | string | No | Comma-separated list of ISO 3166-1 alpha-2 country codes \(e.g., "US,SE"\) | +| `exchanges` | string | No | Comma-separated list of exchange symbols, without whitespace \(e.g., "NasdaqGS"\) | +| `startDate` | string | No | Only return audio dated on or after this ISO 8601 date \(e.g., "2024-01-01"\) | +| `endDate` | string | No | Only return audio dated on or before this ISO 8601 date \(e.g., "2024-12-31"\) | +| `expandEvent` | boolean | No | Include expanded event details on each audio recording | +| `updatedAfter` | string | No | Only return data updated after this ISO 8601 date \(e.g., "2024-01-01"\) | +| `updatedBefore` | string | No | Only return data updated before this ISO 8601 date \(e.g., "2024-12-31"\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | +| `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `audioRecordings` | array | Audio recordings matching the filters | +| ↳ `id` | number | Quartr audio ID | +| ↳ `companyId` | number | Quartr company ID | +| ↳ `eventId` | number | Quartr event ID | +| ↳ `fileUrl` | string | Download URL of the audio file \(MPEG\) | +| ↳ `streamUrl` | string | Streaming URL of the audio \(M3U8\) | +| ↳ `qna` | number | Timestamp in seconds where the Q&A section starts | +| ↳ `audioMetadata` | object | Audio file metadata | +| ↳ `size` | string | File size \(e.g., "200.00 MB"\) | +| ↳ `duration` | number | Duration in seconds | +| ↳ `encoding` | string | Audio encoding | +| ↳ `mimetype` | string | Audio MIME type | +| ↳ `createdAt` | string | Creation timestamp \(ISO 8601\) | +| ↳ `updatedAt` | string | Last update timestamp \(ISO 8601\) | +| ↳ `event` | object | Expanded event details \(present when event expansion is requested\) | +| ↳ `title` | string | Event title | +| ↳ `typeId` | number | Event type ID | +| ↳ `fiscalYear` | number | Fiscal year | +| ↳ `fiscalPeriod` | string | Fiscal period \(e.g., "Q1"\) | +| ↳ `language` | string | Event language code | +| ↳ `date` | string | Event date \(ISO 8601\) | +| `nextCursor` | number | Cursor for fetching the next page of results \(null when no more pages\) | + +### `quartr_get_audio` + +Retrieve an archived event audio recording from Quartr by its audio ID. Returns download (MPEG) and streaming (M3U8) URLs. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Quartr API key | +| `audioId` | number | Yes | Quartr audio ID \(e.g., 123964\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `audio` | object | The requested audio recording | +| ↳ `id` | number | Quartr audio ID | +| ↳ `companyId` | number | Quartr company ID | +| ↳ `eventId` | number | Quartr event ID | +| ↳ `fileUrl` | string | Download URL of the audio file \(MPEG\) | +| ↳ `streamUrl` | string | Streaming URL of the audio \(M3U8\) | +| ↳ `qna` | number | Timestamp in seconds where the Q&A section starts | +| ↳ `audioMetadata` | object | Audio file metadata | +| ↳ `size` | string | File size \(e.g., "200.00 MB"\) | +| ↳ `duration` | number | Duration in seconds | +| ↳ `encoding` | string | Audio encoding | +| ↳ `mimetype` | string | Audio MIME type | +| ↳ `createdAt` | string | Creation timestamp \(ISO 8601\) | +| ↳ `updatedAt` | string | Last update timestamp \(ISO 8601\) | +| ↳ `event` | object | Expanded event details \(present when event expansion is requested\) | +| ↳ `title` | string | Event title | +| ↳ `typeId` | number | Event type ID | +| ↳ `fiscalYear` | number | Fiscal year | +| ↳ `fiscalPeriod` | string | Fiscal period \(e.g., "Q1"\) | +| ↳ `language` | string | Event language code | +| ↳ `date` | string | Event date \(ISO 8601\) | + +### `quartr_list_live_events` + +List live and upcoming events from Quartr with live audio and transcript stream URLs, filterable by company, live state, and date range. + +#### Input + +| Parameter | Type | Required | Description | +| --------- | ---- | -------- | ----------- | +| `apiKey` | string | Yes | Quartr API key | +| `companyIds` | string | No | Comma-separated list of Quartr company IDs \(e.g., "4742,128"\) | +| `eventIds` | string | No | Comma-separated list of Quartr event IDs \(e.g., "128301"\) | +| `tickers` | string | No | Comma-separated list of company tickers \(e.g., "AAPL,MSFT"\) | +| `isins` | string | No | Comma-separated list of ISINs \(e.g., "US0378331005"\) | +| `ciks` | string | No | Comma-separated list of SEC CIKs \(e.g., "0000320193"\) | +| `countries` | string | No | Comma-separated list of ISO 3166-1 alpha-2 country codes \(e.g., "US,SE"\) | +| `exchanges` | string | No | Comma-separated list of exchange symbols, without whitespace \(e.g., "NasdaqGS"\) | +| `states` | string | No | Comma-separated list of live states to filter by: notLive, willBeLive, live, liveFailedInterrupted, liveFailedNoAccess | +| `startDate` | string | No | Only return events on or after this ISO 8601 date \(e.g., "2024-01-01"\) | +| `endDate` | string | No | Only return events on or before this ISO 8601 date \(e.g., "2024-12-31"\) | +| `transcriptVersion` | string | No | Version of the live transcript stream: "1.6" or "1.7" \(default: 1.6\) | +| `updatedAfter` | string | No | Only return data updated after this ISO 8601 date \(e.g., "2024-01-01"\) | +| `updatedBefore` | string | No | Only return data updated before this ISO 8601 date \(e.g., "2024-12-31"\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | +| `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | + +#### Output + +| Parameter | Type | Description | +| --------- | ---- | ----------- | +| `liveEvents` | array | Live events matching the filters | +| ↳ `id` | number | Quartr live event ID | +| ↳ `eventId` | number | Quartr event ID | +| ↳ `companyId` | number | Quartr company ID | +| ↳ `date` | string | Scheduled event date \(ISO 8601\) | +| ↳ `wentLiveAt` | string | Timestamp when the event went live \(ISO 8601\) | +| ↳ `state` | string | Live state \(notLive, willBeLive, live, liveFailedInterrupted, liveFailedNoAccess, recordingAvailable\) | +| ↳ `audio` | string | URL of the live audio stream or recording | +| ↳ `transcript` | string | URL of the live transcript stream \(JSON Lines\) | +| ↳ `createdAt` | string | Creation timestamp \(ISO 8601\) | +| ↳ `updatedAt` | string | Last update timestamp \(ISO 8601\) | +| `nextCursor` | number | Cursor for fetching the next page of results \(null when no more pages\) | + + diff --git a/apps/sim/blocks/blocks/quartr.ts b/apps/sim/blocks/blocks/quartr.ts new file mode 100644 index 0000000000..6ee6f698b6 --- /dev/null +++ b/apps/sim/blocks/blocks/quartr.ts @@ -0,0 +1,644 @@ +import { QuartrIcon } from '@/components/icons' +import type { BlockConfig, BlockMeta } from '@/blocks/types' +import { AuthMode, IntegrationType } from '@/blocks/types' +import type { ToolResponse } from '@/tools/types' + +const ALL_LIST_OPERATIONS = [ + 'list_companies', + 'list_events', + 'list_event_types', + 'list_documents', + 'list_document_types', + 'list_reports', + 'list_slide_decks', + 'list_transcripts', + 'list_audio', + 'list_live_events', +] + +const COMPANY_SCOPED_LIST_OPERATIONS = [ + 'list_companies', + 'list_events', + 'list_documents', + 'list_reports', + 'list_slide_decks', + 'list_transcripts', + 'list_audio', + 'list_live_events', +] + +const DOCUMENT_LIST_OPERATIONS = [ + 'list_documents', + 'list_reports', + 'list_slide_decks', + 'list_transcripts', +] + +const EVENT_SCOPED_LIST_OPERATIONS = [...DOCUMENT_LIST_OPERATIONS, 'list_audio', 'list_live_events'] + +const DATE_RANGE_LIST_OPERATIONS = [ + 'list_events', + ...DOCUMENT_LIST_OPERATIONS, + 'list_audio', + 'list_live_events', +] + +export const QuartrBlock: BlockConfig = { + type: 'quartr', + name: 'Quartr', + description: 'Access earnings calls, transcripts, filings, and slides', + authMode: AuthMode.ApiKey, + longDescription: + 'Integrate Quartr into the workflow. Look up public companies, corporate events, and event types; fetch AI-generated event summaries; list and download filings, reports, slide decks, and transcripts; and access archived audio and live event streams. Requires API Key.', + category: 'tools', + integrationType: IntegrationType.Analytics, + docsLink: 'https://docs.sim.ai/integrations/quartr', + bgColor: '#000000', + icon: QuartrIcon, + subBlocks: [ + { + id: 'operation', + title: 'Operation', + type: 'dropdown', + options: [ + { label: 'List Companies', id: 'list_companies' }, + { label: 'Get Company', id: 'get_company' }, + { label: 'List Events', id: 'list_events' }, + { label: 'Get Event', id: 'get_event' }, + { label: 'Get Event Summary', id: 'get_event_summary' }, + { label: 'List Event Types', id: 'list_event_types' }, + { label: 'List Documents', id: 'list_documents' }, + { label: 'List Document Types', id: 'list_document_types' }, + { label: 'List Reports', id: 'list_reports' }, + { label: 'Get Report', id: 'get_report' }, + { label: 'List Slide Decks', id: 'list_slide_decks' }, + { label: 'Get Slide Deck', id: 'get_slide_deck' }, + { label: 'List Transcripts', id: 'list_transcripts' }, + { label: 'Get Transcript', id: 'get_transcript' }, + { label: 'List Audio', id: 'list_audio' }, + { label: 'Get Audio', id: 'get_audio' }, + { label: 'List Live Events', id: 'list_live_events' }, + ], + value: () => 'list_companies', + }, + { + id: 'companyId', + title: 'Company ID', + type: 'short-input', + placeholder: 'Quartr company ID (e.g., 4742)', + condition: { field: 'operation', value: 'get_company' }, + required: true, + }, + { + id: 'eventId', + title: 'Event ID', + type: 'short-input', + placeholder: 'Quartr event ID (e.g., 128301)', + condition: { field: 'operation', value: ['get_event', 'get_event_summary'] }, + required: true, + }, + { + id: 'summaryLength', + title: 'Summary Length', + type: 'dropdown', + options: [ + { label: 'One Line', id: 'line' }, + { label: 'Short', id: 'short' }, + { label: 'Long', id: 'long' }, + ], + value: () => 'short', + condition: { field: 'operation', value: 'get_event_summary' }, + }, + { + id: 'plainSummary', + title: 'Plain Text Summary', + type: 'switch', + condition: { field: 'operation', value: 'get_event_summary' }, + }, + { + id: 'reportId', + title: 'Report ID', + type: 'short-input', + placeholder: 'Quartr document ID of the report (e.g., 432907)', + condition: { field: 'operation', value: 'get_report' }, + required: true, + }, + { + id: 'slideDeckId', + title: 'Slide Deck ID', + type: 'short-input', + placeholder: 'Quartr document ID of the slide deck (e.g., 432907)', + condition: { field: 'operation', value: 'get_slide_deck' }, + required: true, + }, + { + id: 'transcriptId', + title: 'Transcript ID', + type: 'short-input', + placeholder: 'Quartr document ID of the transcript (e.g., 432907)', + condition: { field: 'operation', value: 'get_transcript' }, + required: true, + }, + { + id: 'audioId', + title: 'Audio ID', + type: 'short-input', + placeholder: 'Quartr audio ID (e.g., 123964)', + condition: { field: 'operation', value: 'get_audio' }, + required: true, + }, + { + id: 'companyIds', + title: 'Company IDs', + type: 'short-input', + placeholder: 'Comma-separated Quartr company IDs (e.g., 4742,128)', + condition: { field: 'operation', value: COMPANY_SCOPED_LIST_OPERATIONS }, + }, + { + id: 'eventIds', + title: 'Event IDs', + type: 'short-input', + placeholder: 'Comma-separated Quartr event IDs (e.g., 128301)', + condition: { field: 'operation', value: EVENT_SCOPED_LIST_OPERATIONS }, + }, + { + id: 'tickers', + title: 'Tickers', + type: 'short-input', + placeholder: 'Comma-separated tickers (e.g., AAPL,MSFT)', + condition: { field: 'operation', value: COMPANY_SCOPED_LIST_OPERATIONS }, + }, + { + id: 'isins', + title: 'ISINs', + type: 'short-input', + placeholder: 'Comma-separated ISINs (e.g., US0378331005)', + condition: { field: 'operation', value: COMPANY_SCOPED_LIST_OPERATIONS }, + mode: 'advanced', + }, + { + id: 'ciks', + title: 'CIKs', + type: 'short-input', + placeholder: 'Comma-separated SEC CIKs (e.g., 0000320193)', + condition: { field: 'operation', value: COMPANY_SCOPED_LIST_OPERATIONS }, + mode: 'advanced', + }, + { + id: 'openfigis', + title: 'OpenFIGIs', + type: 'short-input', + placeholder: 'Comma-separated OpenFIGI codes (e.g., BBG001S5N8V8)', + condition: { field: 'operation', value: 'list_companies' }, + mode: 'advanced', + }, + { + id: 'countries', + title: 'Countries', + type: 'short-input', + placeholder: 'Comma-separated ISO country codes (e.g., US,SE)', + condition: { field: 'operation', value: COMPANY_SCOPED_LIST_OPERATIONS }, + mode: 'advanced', + }, + { + id: 'exchanges', + title: 'Exchanges', + type: 'short-input', + placeholder: 'Comma-separated exchange symbols (e.g., NasdaqGS)', + condition: { field: 'operation', value: COMPANY_SCOPED_LIST_OPERATIONS }, + mode: 'advanced', + }, + { + id: 'eventTypeIds', + title: 'Event Type IDs', + type: 'short-input', + placeholder: 'Comma-separated event type IDs (e.g., 26,27)', + condition: { field: 'operation', value: 'list_events' }, + }, + { + id: 'documentTypeIds', + title: 'Document Type IDs', + type: 'short-input', + placeholder: 'Comma-separated document type IDs (e.g., 7,10)', + condition: { field: 'operation', value: DOCUMENT_LIST_OPERATIONS }, + mode: 'advanced', + }, + { + id: 'documentGroupIds', + title: 'Document Group IDs', + type: 'short-input', + placeholder: '1=Earnings Release, 3=Interim Report, 4=Annual Report...', + condition: { field: 'operation', value: DOCUMENT_LIST_OPERATIONS }, + }, + { + id: 'states', + title: 'Live States', + type: 'short-input', + placeholder: 'Comma-separated states (e.g., live,willBeLive)', + condition: { field: 'operation', value: 'list_live_events' }, + }, + { + id: 'startDate', + title: 'Start Date', + type: 'short-input', + placeholder: 'ISO 8601 date (e.g., 2024-01-01)', + condition: { field: 'operation', value: DATE_RANGE_LIST_OPERATIONS }, + wandConfig: { + enabled: true, + prompt: + 'Generate an ISO 8601 date (e.g., 2024-01-01) for the start of the requested range. Return ONLY the date string - no explanations, no extra text.', + generationType: 'timestamp', + }, + }, + { + id: 'endDate', + title: 'End Date', + type: 'short-input', + placeholder: 'ISO 8601 date (e.g., 2024-12-31)', + condition: { field: 'operation', value: DATE_RANGE_LIST_OPERATIONS }, + wandConfig: { + enabled: true, + prompt: + 'Generate an ISO 8601 date (e.g., 2024-12-31) for the end of the requested range. Return ONLY the date string - no explanations, no extra text.', + generationType: 'timestamp', + }, + }, + { + id: 'transcriptVersion', + title: 'Live Transcript Version', + type: 'dropdown', + options: [ + { label: '1.6', id: '1.6' }, + { label: '1.7', id: '1.7' }, + ], + value: () => '1.6', + condition: { field: 'operation', value: 'list_live_events' }, + mode: 'advanced', + }, + { + id: 'sortBy', + title: 'Sort By', + type: 'dropdown', + options: [ + { label: 'ID', id: 'id' }, + { label: 'Date', id: 'date' }, + ], + value: () => 'id', + condition: { field: 'operation', value: 'list_events' }, + mode: 'advanced', + }, + { + id: 'expandEvent', + title: 'Include Event Details', + type: 'switch', + condition: { + field: 'operation', + value: [...DOCUMENT_LIST_OPERATIONS, 'list_audio'], + }, + mode: 'advanced', + }, + { + id: 'updatedAfter', + title: 'Updated After', + type: 'short-input', + placeholder: 'ISO 8601 date (e.g., 2024-01-01)', + condition: { field: 'operation', value: ALL_LIST_OPERATIONS }, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate an ISO 8601 date (e.g., 2024-01-01) for filtering data updated after this date. Return ONLY the date string - no explanations, no extra text.', + generationType: 'timestamp', + }, + }, + { + id: 'updatedBefore', + title: 'Updated Before', + type: 'short-input', + placeholder: 'ISO 8601 date (e.g., 2024-12-31)', + condition: { field: 'operation', value: ALL_LIST_OPERATIONS }, + mode: 'advanced', + wandConfig: { + enabled: true, + prompt: + 'Generate an ISO 8601 date (e.g., 2024-12-31) for filtering data updated before this date. Return ONLY the date string - no explanations, no extra text.', + generationType: 'timestamp', + }, + }, + { + id: 'limit', + title: 'Limit', + type: 'short-input', + placeholder: '10', + condition: { field: 'operation', value: ALL_LIST_OPERATIONS }, + mode: 'advanced', + }, + { + id: 'cursor', + title: 'Cursor', + type: 'short-input', + placeholder: 'nextCursor from the previous response', + condition: { field: 'operation', value: ALL_LIST_OPERATIONS }, + mode: 'advanced', + }, + { + id: 'direction', + title: 'Sort Direction', + type: 'dropdown', + options: [ + { label: 'Ascending', id: 'asc' }, + { label: 'Descending', id: 'desc' }, + ], + value: () => 'asc', + condition: { field: 'operation', value: ALL_LIST_OPERATIONS }, + mode: 'advanced', + }, + { + id: 'apiKey', + title: 'API Key', + type: 'short-input', + placeholder: 'Enter your Quartr API key', + password: true, + required: true, + }, + ], + tools: { + access: [ + 'quartr_list_companies', + 'quartr_get_company', + 'quartr_list_events', + 'quartr_get_event', + 'quartr_get_event_summary', + 'quartr_list_event_types', + 'quartr_list_documents', + 'quartr_list_document_types', + 'quartr_list_reports', + 'quartr_get_report', + 'quartr_list_slide_decks', + 'quartr_get_slide_deck', + 'quartr_list_transcripts', + 'quartr_get_transcript', + 'quartr_list_audio', + 'quartr_get_audio', + 'quartr_list_live_events', + ], + config: { + tool: (params) => `quartr_${params.operation}`, + }, + }, + inputs: { + operation: { type: 'string', description: 'Operation to perform' }, + apiKey: { type: 'string', description: 'Quartr API key' }, + companyId: { type: 'number', description: 'Quartr company ID' }, + eventId: { type: 'number', description: 'Quartr event ID' }, + summaryLength: { type: 'string', description: 'Summary length preset' }, + plainSummary: { type: 'boolean', description: 'Plain text summary without source tags' }, + reportId: { type: 'number', description: 'Quartr document ID of the report' }, + slideDeckId: { type: 'number', description: 'Quartr document ID of the slide deck' }, + transcriptId: { type: 'number', description: 'Quartr document ID of the transcript' }, + audioId: { type: 'number', description: 'Quartr audio ID' }, + companyIds: { type: 'string', description: 'Comma-separated Quartr company IDs' }, + eventIds: { type: 'string', description: 'Comma-separated Quartr event IDs' }, + tickers: { type: 'string', description: 'Comma-separated company tickers' }, + isins: { type: 'string', description: 'Comma-separated ISINs' }, + ciks: { type: 'string', description: 'Comma-separated SEC CIKs' }, + openfigis: { type: 'string', description: 'Comma-separated OpenFIGI codes' }, + countries: { type: 'string', description: 'Comma-separated ISO country codes' }, + exchanges: { type: 'string', description: 'Comma-separated exchange symbols' }, + eventTypeIds: { type: 'string', description: 'Comma-separated event type IDs' }, + documentTypeIds: { type: 'string', description: 'Comma-separated document type IDs' }, + documentGroupIds: { type: 'string', description: 'Comma-separated document group IDs' }, + states: { type: 'string', description: 'Comma-separated live states' }, + transcriptVersion: { type: 'string', description: 'Live transcript stream version' }, + startDate: { type: 'string', description: 'Start date filter (ISO 8601)' }, + endDate: { type: 'string', description: 'End date filter (ISO 8601)' }, + sortBy: { type: 'string', description: 'Field to sort events by' }, + expandEvent: { type: 'boolean', description: 'Include expanded event details' }, + updatedAfter: { type: 'string', description: 'Updated-after date filter (ISO 8601)' }, + updatedBefore: { type: 'string', description: 'Updated-before date filter (ISO 8601)' }, + limit: { type: 'number', description: 'Maximum number of items to return' }, + cursor: { type: 'number', description: 'Pagination cursor from the previous response' }, + direction: { type: 'string', description: 'Sort direction (asc or desc)' }, + }, + outputs: { + companies: { + type: 'array', + description: 'Companies matching the filters', + condition: { field: 'operation', value: 'list_companies' }, + }, + company: { + type: 'json', + description: 'The requested company', + condition: { field: 'operation', value: 'get_company' }, + }, + events: { + type: 'array', + description: 'Events matching the filters', + condition: { field: 'operation', value: 'list_events' }, + }, + event: { + type: 'json', + description: 'The requested event', + condition: { field: 'operation', value: 'get_event' }, + }, + summary: { + type: 'string', + description: 'AI-generated event summary in Markdown', + condition: { field: 'operation', value: 'get_event_summary' }, + }, + sources: { + type: 'array', + description: 'Source documents referenced by the summary', + condition: { field: 'operation', value: 'get_event_summary' }, + }, + summaryId: { + type: 'number', + description: 'Quartr summary ID', + condition: { field: 'operation', value: 'get_event_summary' }, + }, + summaryCreatedAt: { + type: 'string', + description: 'Summary creation timestamp (ISO 8601)', + condition: { field: 'operation', value: 'get_event_summary' }, + }, + summaryUpdatedAt: { + type: 'string', + description: 'Summary last update timestamp (ISO 8601)', + condition: { field: 'operation', value: 'get_event_summary' }, + }, + eventTypes: { + type: 'array', + description: 'Available event types', + condition: { field: 'operation', value: 'list_event_types' }, + }, + documentTypes: { + type: 'array', + description: 'Available document types', + condition: { field: 'operation', value: 'list_document_types' }, + }, + documents: { + type: 'array', + description: 'Documents matching the filters', + condition: { field: 'operation', value: 'list_documents' }, + }, + reports: { + type: 'array', + description: 'Reports matching the filters', + condition: { field: 'operation', value: 'list_reports' }, + }, + slideDecks: { + type: 'array', + description: 'Slide decks matching the filters', + condition: { field: 'operation', value: 'list_slide_decks' }, + }, + transcripts: { + type: 'array', + description: 'Transcripts matching the filters', + condition: { field: 'operation', value: 'list_transcripts' }, + }, + document: { + type: 'json', + description: 'Document metadata', + condition: { field: 'operation', value: ['get_report', 'get_slide_deck', 'get_transcript'] }, + }, + fileUrl: { + type: 'string', + description: 'URL of the document file', + condition: { field: 'operation', value: ['get_report', 'get_slide_deck', 'get_transcript'] }, + }, + file: { + type: 'file', + description: 'Downloaded document file stored in execution files', + condition: { field: 'operation', value: ['get_report', 'get_slide_deck', 'get_transcript'] }, + }, + audioRecordings: { + type: 'array', + description: 'Audio recordings matching the filters', + condition: { field: 'operation', value: 'list_audio' }, + }, + audio: { + type: 'json', + description: 'The requested audio recording', + condition: { field: 'operation', value: 'get_audio' }, + }, + liveEvents: { + type: 'array', + description: 'Live events matching the filters', + condition: { field: 'operation', value: 'list_live_events' }, + }, + nextCursor: { + type: 'number', + description: 'Cursor for fetching the next page of results (null when no more pages)', + condition: { field: 'operation', value: ALL_LIST_OPERATIONS }, + }, + }, +} + +export const QuartrBlockMeta = { + tags: ['data-analytics', 'enrichment', 'document-processing'], + templates: [ + { + icon: QuartrIcon, + title: 'Quartr earnings call digest', + prompt: + 'Create a scheduled workflow that lists yesterday’s Quartr events for my watchlist tickers, fetches the AI-generated summary for each event, and posts a digest with source links to Slack.', + modules: ['scheduled', 'agent', 'workflows'], + category: 'productivity', + tags: ['research', 'reporting'], + alsoIntegrations: ['slack'], + }, + { + icon: QuartrIcon, + title: 'Quartr transcript knowledge base', + prompt: + 'Build a scheduled workflow that lists new Quartr earnings call transcripts for companies I follow, downloads each transcript file, and indexes the content into a knowledge base so agents can answer questions about past calls.', + modules: ['scheduled', 'knowledge-base', 'workflows'], + category: 'productivity', + tags: ['research', 'knowledge-base'], + }, + { + icon: QuartrIcon, + title: 'Quartr filing watcher', + prompt: + 'Create a scheduled workflow that checks Quartr daily for new annual and interim reports from my portfolio companies, downloads each report PDF to Files, and emails me a summary of what was filed.', + modules: ['scheduled', 'files', 'agent', 'workflows'], + category: 'operations', + tags: ['monitoring', 'automation'], + alsoIntegrations: ['gmail'], + }, + { + icon: QuartrIcon, + title: 'Quartr slide deck analyst', + prompt: + 'Build a workflow that fetches the latest Quartr slide deck for a given ticker, has an agent extract guidance, KPIs, and notable changes from the deck, and writes the analysis to a table.', + modules: ['agent', 'tables', 'workflows'], + category: 'productivity', + tags: ['research', 'document-processing'], + }, + { + icon: QuartrIcon, + title: 'Quartr live earnings monitor', + prompt: + 'Create a scheduled workflow that polls Quartr live events for my watchlist, and when a company goes live, posts the live audio and transcript stream links to a Slack channel.', + modules: ['scheduled', 'workflows'], + category: 'operations', + tags: ['monitoring', 'events'], + alsoIntegrations: ['slack'], + }, + { + icon: QuartrIcon, + title: 'Quartr competitor earnings tracker', + prompt: + 'Build a workflow that reads competitor tickers from a table, lists each company’s recent Quartr events and event summaries, and logs revenue and guidance highlights back to the table for quarter-over-quarter comparison.', + modules: ['tables', 'agent', 'workflows'], + category: 'sales', + tags: ['research', 'sales'], + }, + { + icon: QuartrIcon, + title: 'Quartr earnings Q&A agent', + prompt: + 'Create an agent that answers questions about a company’s earnings by looking up the company on Quartr, finding its latest earnings call event, and grounding answers in the event summary and transcript.', + modules: ['agent', 'workflows'], + category: 'productivity', + tags: ['research', 'agentic'], + }, + ], + skills: [ + { + name: 'summarize-earnings-call', + description: + 'Find a company’s latest earnings call on Quartr and return its AI-generated summary with sources.', + content: + '# Summarize an Earnings Call\n\nTurn a ticker into a sourced summary of the company’s most recent earnings call.\n\n## Steps\n1. Use the List Companies operation with the ticker in Tickers to resolve the Quartr company ID.\n2. Use List Events with that ID in Company IDs, Sort By set to Date, and Sort Direction set to Descending to find the latest earnings event.\n3. Use Get Event Summary with the event ID. Pick Summary Length: One Line for a headline, Short for a digest, or Long for full detail.\n4. Keep Plain Text Summary off if you want the embedded source tags, and use the sources output to cite documents.\n\n## Output\nReturn the summary text followed by the event title, date, and the source document IDs it references.', + }, + { + name: 'download-earnings-transcript', + description: + 'Download the structured transcript JSON for a company’s earnings call for downstream analysis.', + content: + '# Download an Earnings Call Transcript\n\nFetch a transcript with timestamps and speaker identification as a workflow file.\n\n## Steps\n1. Resolve the company with List Companies (ticker, ISIN, or CIK).\n2. Use List Transcripts with the company ID in Company IDs and a date range to find the right transcript document.\n3. Use Get Transcript with that document ID. The transcript JSON is downloaded and stored as an execution file.\n4. Pass the file to an agent or knowledge base to analyze paragraphs, sentences, timestamps, and speakers.\n\n## Output\nReturn the transcript file plus the document metadata (event title, fiscal period, and date).', + }, + { + name: 'fetch-latest-filings', + description: + 'List a company’s recent filings and reports on Quartr and download the report PDFs.', + content: + '# Fetch the Latest Filings and Reports\n\nPull recent 10-Ks, 10-Qs, earnings releases, or annual reports for a company.\n\n## Steps\n1. Resolve the company with List Companies using its ticker or CIK.\n2. Use List Reports with the company ID in Company IDs. Narrow with Document Group IDs (1 = Earnings Release, 3 = Interim Report, 4 = Annual Report) or a date range.\n3. Use Get Report with each document ID to download the PDF into execution files.\n4. Optionally use List Document Types to map type IDs to filing forms like 10-Q.\n\n## Output\nReturn the report files with each document’s type, event, and filing date.', + }, + { + name: 'monitor-live-earnings', + description: + 'Check which companies are live on Quartr right now and surface their audio and transcript streams.', + content: + '# Monitor Live Earnings Calls\n\nWatch for companies going live and grab their stream URLs.\n\n## Steps\n1. Use List Live Events with Live States set to live (or willBeLive to see what is coming up).\n2. Filter to your watchlist with Company IDs or Tickers.\n3. Read each live event’s state, audio stream URL, and transcript stream URL from the output.\n4. Run the workflow on a schedule and alert when a watched company’s state changes to live.\n\n## Output\nReturn the live companies with their event IDs, states, and audio/transcript stream URLs.', + }, + { + name: 'analyze-investor-slides', + description: + 'Download a company’s latest investor presentation from Quartr and extract key takeaways.', + content: + '# Analyze an Investor Slide Deck\n\nGet the latest presentation PDF and have an agent extract what matters.\n\n## Steps\n1. Resolve the company with List Companies and find the relevant event with List Events.\n2. Use List Slide Decks with the event ID in Event IDs (or the company ID and a date range) to find the deck.\n3. Use Get Slide Deck with the document ID to download the PDF into execution files.\n4. Pass the file to an agent to extract guidance, KPIs, and notable changes.\n\n## Output\nReturn the slide deck file plus the extracted highlights.', + }, + ], +} as const satisfies BlockMeta diff --git a/apps/sim/blocks/registry.ts b/apps/sim/blocks/registry.ts index daad4c9671..bb3fd882b8 100644 --- a/apps/sim/blocks/registry.ts +++ b/apps/sim/blocks/registry.ts @@ -227,6 +227,7 @@ import { ProfoundBlock, ProfoundBlockMeta } from '@/blocks/blocks/profound' import { ProspeoBlock, ProspeoBlockMeta } from '@/blocks/blocks/prospeo' import { PulseBlock, PulseBlockMeta, PulseV2Block } from '@/blocks/blocks/pulse' import { QdrantBlock, QdrantBlockMeta } from '@/blocks/blocks/qdrant' +import { QuartrBlock, QuartrBlockMeta } from '@/blocks/blocks/quartr' import { QuiverBlock, QuiverBlockMeta } from '@/blocks/blocks/quiver' import { RailwayBlock, RailwayBlockMeta } from '@/blocks/blocks/railway' import { RB2BBlock, RB2BBlockMeta } from '@/blocks/blocks/rb2b' @@ -520,6 +521,7 @@ const BLOCK_REGISTRY: Record = { pulse: PulseBlock, pulse_v2: PulseV2Block, qdrant: QdrantBlock, + quartr: QuartrBlock, quiver: QuiverBlock, railway: RailwayBlock, rb2b: RB2BBlock, @@ -784,6 +786,7 @@ const BLOCK_META_REGISTRY: Record = { prospeo: ProspeoBlockMeta, pulse: PulseBlockMeta, qdrant: QdrantBlockMeta, + quartr: QuartrBlockMeta, quiver: QuiverBlockMeta, railway: RailwayBlockMeta, rb2b: RB2BBlockMeta, diff --git a/apps/sim/components/icons.tsx b/apps/sim/components/icons.tsx index ae3f48d4c0..2dd06da0b5 100644 --- a/apps/sim/components/icons.tsx +++ b/apps/sim/components/icons.tsx @@ -3705,6 +3705,50 @@ export function QdrantIcon(props: SVGProps) { ) } +export function QuartrIcon(props: SVGProps) { + return ( + + + + + + + + + + + + + ) +} + export function QuiverIcon(props: SVGProps) { return ( = { prospeo: ProspeoIcon, pulse_v2: PulseIcon, qdrant: QdrantIcon, + quartr: QuartrIcon, quiver: QuiverIcon, railway: RailwayIcon, rb2b: RB2BIcon, diff --git a/apps/sim/lib/integrations/integrations.json b/apps/sim/lib/integrations/integrations.json index 4b935fc0bb..84f5f663b6 100644 --- a/apps/sim/lib/integrations/integrations.json +++ b/apps/sim/lib/integrations/integrations.json @@ -11644,6 +11644,93 @@ "integrationType": "databases", "tags": ["vector-search", "knowledge-base"] }, + { + "type": "quartr", + "slug": "quartr", + "name": "Quartr", + "description": "Access earnings calls, transcripts, filings, and slides", + "longDescription": "Integrate Quartr into the workflow. Look up public companies, corporate events, and event types; fetch AI-generated event summaries; list and download filings, reports, slide decks, and transcripts; and access archived audio and live event streams. Requires API Key.", + "bgColor": "#000000", + "iconName": "QuartrIcon", + "docsUrl": "https://docs.sim.ai/integrations/quartr", + "operations": [ + { + "name": "List Companies", + "description": "List companies covered by Quartr, filterable by ticker, ISIN, CIK, OpenFIGI, country, and exchange." + }, + { + "name": "Get Company", + "description": "Retrieve a single company from Quartr by its company ID." + }, + { + "name": "List Events", + "description": "List corporate events (earnings calls, capital markets days, etc.) from Quartr, filterable by company, event type, and date range." + }, + { + "name": "Get Event", + "description": "Retrieve a single corporate event from Quartr by its event ID." + }, + { + "name": "Get Event Summary", + "description": "Retrieve the AI-generated summary of a corporate event from Quartr, with selectable length and optional plain-text formatting." + }, + { + "name": "List Event Types", + "description": "List the event types available in Quartr (e.g., earnings calls), useful for filtering events by type ID." + }, + { + "name": "List Documents", + "description": "List documents of all kinds (reports, slide decks, and transcripts) from Quartr, filterable by company, event, document type, document group, and date range." + }, + { + "name": "List Document Types", + "description": "List the document types available in Quartr (e.g., 10-Q quarterly reports), useful for filtering documents by type ID." + }, + { + "name": "List Reports", + "description": "List filings and reports (10-K, 10-Q, earnings releases, etc.) from Quartr, filterable by company, event, document type, document group, and date range." + }, + { + "name": "Get Report", + "description": "Retrieve a filing or report (10-K, 10-Q, earnings release, etc.) from Quartr by its document ID and download the PDF file." + }, + { + "name": "List Slide Decks", + "description": "List slide presentations from Quartr, filterable by company, event, document type, document group, and date range." + }, + { + "name": "Get Slide Deck", + "description": "Retrieve a slide presentation from Quartr by its document ID and download the PDF file." + }, + { + "name": "List Transcripts", + "description": "List event transcripts from Quartr, filterable by company, event, document type, document group, and date range." + }, + { + "name": "Get Transcript", + "description": "Retrieve an event transcript from Quartr by its document ID and download the transcript JSON file (paragraphs, sentences, timestamps, and speaker identification)." + }, + { + "name": "List Audio", + "description": "List archived event audio recordings from Quartr, filterable by company, event, and date range. Returns download (MPEG) and streaming (M3U8) URLs." + }, + { + "name": "Get Audio", + "description": "Retrieve an archived event audio recording from Quartr by its audio ID. Returns download (MPEG) and streaming (M3U8) URLs." + }, + { + "name": "List Live Events", + "description": "List live and upcoming events from Quartr with live audio and transcript stream URLs, filterable by company, live state, and date range." + } + ], + "operationCount": 17, + "triggers": [], + "triggerCount": 0, + "authType": "api-key", + "category": "tools", + "integrationType": "analytics", + "tags": ["data-analytics", "enrichment", "document-processing"] + }, { "type": "quiver", "slug": "quiver", diff --git a/apps/sim/tools/quartr/get_audio.ts b/apps/sim/tools/quartr/get_audio.ts new file mode 100644 index 0000000000..6837be5c14 --- /dev/null +++ b/apps/sim/tools/quartr/get_audio.ts @@ -0,0 +1,60 @@ +import { + QUARTR_AUDIO_OUTPUT_PROPERTIES, + type QuartrAudioDto, + type QuartrGetAudioParams, + type QuartrGetAudioResponse, + type QuartrSingleDto, +} from '@/tools/quartr/types' +import { buildQuartrUrl, mapQuartrAudio, parseQuartrResponse } from '@/tools/quartr/utils' +import type { ToolConfig } from '@/tools/types' + +export const quartrGetAudioTool: ToolConfig = { + id: 'quartr_get_audio', + name: 'Quartr Get Audio', + description: + 'Retrieve an archived event audio recording from Quartr by its audio ID. Returns download (MPEG) and streaming (M3U8) URLs.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Quartr API key', + }, + audioId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'Quartr audio ID (e.g., 123964)', + }, + }, + + request: { + url: (params) => + buildQuartrUrl(`/audio/${encodeURIComponent(String(params.audioId).trim())}`, { + expand: 'event', + }), + method: 'GET', + headers: (params) => ({ 'x-api-key': params.apiKey }), + }, + + transformResponse: async (response) => { + const data = await parseQuartrResponse>(response, 'get audio') + + return { + success: true, + output: { + audio: mapQuartrAudio(data.data), + }, + } + }, + + outputs: { + audio: { + type: 'object', + description: 'The requested audio recording', + properties: QUARTR_AUDIO_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/quartr/get_company.ts b/apps/sim/tools/quartr/get_company.ts new file mode 100644 index 0000000000..3de98d2733 --- /dev/null +++ b/apps/sim/tools/quartr/get_company.ts @@ -0,0 +1,60 @@ +import { + QUARTR_COMPANY_OUTPUT_PROPERTIES, + type QuartrCompanyDto, + type QuartrGetCompanyParams, + type QuartrGetCompanyResponse, + type QuartrSingleDto, +} from '@/tools/quartr/types' +import { buildQuartrUrl, mapQuartrCompany, parseQuartrResponse } from '@/tools/quartr/utils' +import type { ToolConfig } from '@/tools/types' + +export const quartrGetCompanyTool: ToolConfig = { + id: 'quartr_get_company', + name: 'Quartr Get Company', + description: 'Retrieve a single company from Quartr by its company ID.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Quartr API key', + }, + companyId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'Quartr company ID (e.g., 4742)', + }, + }, + + request: { + url: (params) => + buildQuartrUrl(`/companies/${encodeURIComponent(String(params.companyId).trim())}`), + method: 'GET', + headers: (params) => ({ 'x-api-key': params.apiKey }), + }, + + transformResponse: async (response) => { + const data = await parseQuartrResponse>( + response, + 'get company' + ) + + return { + success: true, + output: { + company: mapQuartrCompany(data.data), + }, + } + }, + + outputs: { + company: { + type: 'object', + description: 'The requested company', + properties: QUARTR_COMPANY_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/quartr/get_event.ts b/apps/sim/tools/quartr/get_event.ts new file mode 100644 index 0000000000..c1da673432 --- /dev/null +++ b/apps/sim/tools/quartr/get_event.ts @@ -0,0 +1,56 @@ +import { + QUARTR_EVENT_OUTPUT_PROPERTIES, + type QuartrEventDto, + type QuartrGetEventParams, + type QuartrGetEventResponse, + type QuartrSingleDto, +} from '@/tools/quartr/types' +import { buildQuartrUrl, mapQuartrEvent, parseQuartrResponse } from '@/tools/quartr/utils' +import type { ToolConfig } from '@/tools/types' + +export const quartrGetEventTool: ToolConfig = { + id: 'quartr_get_event', + name: 'Quartr Get Event', + description: 'Retrieve a single corporate event from Quartr by its event ID.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Quartr API key', + }, + eventId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'Quartr event ID (e.g., 128301)', + }, + }, + + request: { + url: (params) => buildQuartrUrl(`/events/${encodeURIComponent(String(params.eventId).trim())}`), + method: 'GET', + headers: (params) => ({ 'x-api-key': params.apiKey }), + }, + + transformResponse: async (response) => { + const data = await parseQuartrResponse>(response, 'get event') + + return { + success: true, + output: { + event: mapQuartrEvent(data.data), + }, + } + }, + + outputs: { + event: { + type: 'object', + description: 'The requested event', + properties: QUARTR_EVENT_OUTPUT_PROPERTIES, + }, + }, +} diff --git a/apps/sim/tools/quartr/get_event_summary.ts b/apps/sim/tools/quartr/get_event_summary.ts new file mode 100644 index 0000000000..37833deaa0 --- /dev/null +++ b/apps/sim/tools/quartr/get_event_summary.ts @@ -0,0 +1,97 @@ +import { + QUARTR_SUMMARY_SOURCE_OUTPUT_PROPERTIES, + type QuartrGetEventSummaryParams, + type QuartrGetEventSummaryResponse, + type QuartrSingleDto, + type QuartrSummaryDto, +} from '@/tools/quartr/types' +import { buildQuartrUrl, mapQuartrSummarySource, parseQuartrResponse } from '@/tools/quartr/utils' +import type { ToolConfig } from '@/tools/types' + +export const quartrGetEventSummaryTool: ToolConfig< + QuartrGetEventSummaryParams, + QuartrGetEventSummaryResponse +> = { + id: 'quartr_get_event_summary', + name: 'Quartr Get Event Summary', + description: + 'Retrieve the AI-generated summary of a corporate event from Quartr, with selectable length and optional plain-text formatting.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Quartr API key', + }, + eventId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'Quartr event ID (e.g., 128301)', + }, + summaryLength: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Length preset for the summary: "line", "short", or "long" (default: short)', + }, + plainSummary: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Return a plain-text summary without embedded document source tags', + }, + }, + + request: { + url: (params) => + buildQuartrUrl(`/events/${encodeURIComponent(String(params.eventId).trim())}/summary`, { + length: params.summaryLength, + plain: params.plainSummary === true ? true : undefined, + }), + method: 'GET', + headers: (params) => ({ 'x-api-key': params.apiKey }), + }, + + transformResponse: async (response) => { + const data = await parseQuartrResponse>( + response, + 'get event summary' + ) + const summary = data.data + + return { + success: true, + output: { + summary: summary.summary, + sources: (summary.sources ?? []).map(mapQuartrSummarySource), + summaryId: summary.id, + summaryCreatedAt: summary.createdAt, + summaryUpdatedAt: summary.updatedAt, + }, + } + }, + + outputs: { + summary: { + type: 'string', + description: 'AI-generated event summary in Markdown', + }, + sources: { + type: 'array', + description: 'Source documents referenced by the summary', + items: { type: 'object', properties: QUARTR_SUMMARY_SOURCE_OUTPUT_PROPERTIES }, + }, + summaryId: { type: 'number', description: 'Quartr summary ID' }, + summaryCreatedAt: { + type: 'string', + description: 'Summary creation timestamp (ISO 8601)', + }, + summaryUpdatedAt: { + type: 'string', + description: 'Summary last update timestamp (ISO 8601)', + }, + }, +} diff --git a/apps/sim/tools/quartr/get_report.ts b/apps/sim/tools/quartr/get_report.ts new file mode 100644 index 0000000000..bee97b24ae --- /dev/null +++ b/apps/sim/tools/quartr/get_report.ts @@ -0,0 +1,77 @@ +import { + QUARTR_DOCUMENT_OUTPUT_PROPERTIES, + type QuartrDocumentDto, + type QuartrGetDocumentFileResponse, + type QuartrGetReportParams, + type QuartrSingleDto, +} from '@/tools/quartr/types' +import { buildQuartrUrl, mapQuartrDocument, parseQuartrResponse } from '@/tools/quartr/utils' +import type { ToolConfig } from '@/tools/types' + +export const quartrGetReportTool: ToolConfig = + { + id: 'quartr_get_report', + name: 'Quartr Get Report', + description: + 'Retrieve a filing or report (10-K, 10-Q, earnings release, etc.) from Quartr by its document ID and download the PDF file.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Quartr API key', + }, + reportId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'Quartr document ID of the report (e.g., 432907)', + }, + }, + + request: { + url: (params) => + buildQuartrUrl(`/documents/reports/${encodeURIComponent(String(params.reportId).trim())}`, { + expand: 'event', + }), + method: 'GET', + headers: (params) => ({ 'x-api-key': params.apiKey }), + }, + + transformResponse: async (response) => { + const data = await parseQuartrResponse>( + response, + 'get report' + ) + const document = mapQuartrDocument(data.data) + + return { + success: true, + output: { + document, + fileUrl: document.fileUrl, + file: { + name: `quartr-report-${document.id}.pdf`, + mimeType: 'application/pdf', + url: document.fileUrl, + }, + }, + } + }, + + outputs: { + document: { + type: 'object', + description: 'Report metadata', + properties: QUARTR_DOCUMENT_OUTPUT_PROPERTIES, + }, + fileUrl: { type: 'string', description: 'URL of the report PDF' }, + file: { + type: 'file', + description: 'Downloaded report PDF stored in execution files', + fileConfig: { mimeType: 'application/pdf', extension: 'pdf' }, + }, + }, + } diff --git a/apps/sim/tools/quartr/get_slide_deck.ts b/apps/sim/tools/quartr/get_slide_deck.ts new file mode 100644 index 0000000000..58135eff6b --- /dev/null +++ b/apps/sim/tools/quartr/get_slide_deck.ts @@ -0,0 +1,79 @@ +import { + QUARTR_DOCUMENT_OUTPUT_PROPERTIES, + type QuartrDocumentDto, + type QuartrGetDocumentFileResponse, + type QuartrGetSlideDeckParams, + type QuartrSingleDto, +} from '@/tools/quartr/types' +import { buildQuartrUrl, mapQuartrDocument, parseQuartrResponse } from '@/tools/quartr/utils' +import type { ToolConfig } from '@/tools/types' + +export const quartrGetSlideDeckTool: ToolConfig< + QuartrGetSlideDeckParams, + QuartrGetDocumentFileResponse +> = { + id: 'quartr_get_slide_deck', + name: 'Quartr Get Slide Deck', + description: + 'Retrieve a slide presentation from Quartr by its document ID and download the PDF file.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Quartr API key', + }, + slideDeckId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'Quartr document ID of the slide deck (e.g., 432907)', + }, + }, + + request: { + url: (params) => + buildQuartrUrl(`/documents/slides/${encodeURIComponent(String(params.slideDeckId).trim())}`, { + expand: 'event', + }), + method: 'GET', + headers: (params) => ({ 'x-api-key': params.apiKey }), + }, + + transformResponse: async (response) => { + const data = await parseQuartrResponse>( + response, + 'get slide deck' + ) + const document = mapQuartrDocument(data.data) + + return { + success: true, + output: { + document, + fileUrl: document.fileUrl, + file: { + name: `quartr-slide-deck-${document.id}.pdf`, + mimeType: 'application/pdf', + url: document.fileUrl, + }, + }, + } + }, + + outputs: { + document: { + type: 'object', + description: 'Slide deck metadata', + properties: QUARTR_DOCUMENT_OUTPUT_PROPERTIES, + }, + fileUrl: { type: 'string', description: 'URL of the slide deck PDF' }, + file: { + type: 'file', + description: 'Downloaded slide deck PDF stored in execution files', + fileConfig: { mimeType: 'application/pdf', extension: 'pdf' }, + }, + }, +} diff --git a/apps/sim/tools/quartr/get_transcript.ts b/apps/sim/tools/quartr/get_transcript.ts new file mode 100644 index 0000000000..54e438cfae --- /dev/null +++ b/apps/sim/tools/quartr/get_transcript.ts @@ -0,0 +1,80 @@ +import { + QUARTR_DOCUMENT_OUTPUT_PROPERTIES, + type QuartrDocumentDto, + type QuartrGetDocumentFileResponse, + type QuartrGetTranscriptParams, + type QuartrSingleDto, +} from '@/tools/quartr/types' +import { buildQuartrUrl, mapQuartrDocument, parseQuartrResponse } from '@/tools/quartr/utils' +import type { ToolConfig } from '@/tools/types' + +export const quartrGetTranscriptTool: ToolConfig< + QuartrGetTranscriptParams, + QuartrGetDocumentFileResponse +> = { + id: 'quartr_get_transcript', + name: 'Quartr Get Transcript', + description: + 'Retrieve an event transcript from Quartr by its document ID and download the transcript JSON file (paragraphs, sentences, timestamps, and speaker identification).', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Quartr API key', + }, + transcriptId: { + type: 'number', + required: true, + visibility: 'user-or-llm', + description: 'Quartr document ID of the transcript (e.g., 432907)', + }, + }, + + request: { + url: (params) => + buildQuartrUrl( + `/documents/transcripts/${encodeURIComponent(String(params.transcriptId).trim())}`, + { expand: 'event' } + ), + method: 'GET', + headers: (params) => ({ 'x-api-key': params.apiKey }), + }, + + transformResponse: async (response) => { + const data = await parseQuartrResponse>( + response, + 'get transcript' + ) + const document = mapQuartrDocument(data.data) + + return { + success: true, + output: { + document, + fileUrl: document.fileUrl, + file: { + name: `quartr-transcript-${document.id}.json`, + mimeType: 'application/json', + url: document.fileUrl, + }, + }, + } + }, + + outputs: { + document: { + type: 'object', + description: 'Transcript metadata', + properties: QUARTR_DOCUMENT_OUTPUT_PROPERTIES, + }, + fileUrl: { type: 'string', description: 'URL of the transcript JSON file' }, + file: { + type: 'file', + description: 'Downloaded transcript JSON file stored in execution files', + fileConfig: { mimeType: 'application/json', extension: 'json' }, + }, + }, +} diff --git a/apps/sim/tools/quartr/index.ts b/apps/sim/tools/quartr/index.ts new file mode 100644 index 0000000000..5f33a7ef45 --- /dev/null +++ b/apps/sim/tools/quartr/index.ts @@ -0,0 +1,17 @@ +export { quartrGetAudioTool } from '@/tools/quartr/get_audio' +export { quartrGetCompanyTool } from '@/tools/quartr/get_company' +export { quartrGetEventTool } from '@/tools/quartr/get_event' +export { quartrGetEventSummaryTool } from '@/tools/quartr/get_event_summary' +export { quartrGetReportTool } from '@/tools/quartr/get_report' +export { quartrGetSlideDeckTool } from '@/tools/quartr/get_slide_deck' +export { quartrGetTranscriptTool } from '@/tools/quartr/get_transcript' +export { quartrListAudioTool } from '@/tools/quartr/list_audio' +export { quartrListCompaniesTool } from '@/tools/quartr/list_companies' +export { quartrListDocumentTypesTool } from '@/tools/quartr/list_document_types' +export { quartrListDocumentsTool } from '@/tools/quartr/list_documents' +export { quartrListEventTypesTool } from '@/tools/quartr/list_event_types' +export { quartrListEventsTool } from '@/tools/quartr/list_events' +export { quartrListLiveEventsTool } from '@/tools/quartr/list_live_events' +export { quartrListReportsTool } from '@/tools/quartr/list_reports' +export { quartrListSlideDecksTool } from '@/tools/quartr/list_slide_decks' +export { quartrListTranscriptsTool } from '@/tools/quartr/list_transcripts' diff --git a/apps/sim/tools/quartr/list_audio.ts b/apps/sim/tools/quartr/list_audio.ts new file mode 100644 index 0000000000..54b2178109 --- /dev/null +++ b/apps/sim/tools/quartr/list_audio.ts @@ -0,0 +1,165 @@ +import { + QUARTR_AUDIO_OUTPUT_PROPERTIES, + type QuartrAudioDto, + type QuartrListAudioParams, + type QuartrListAudioResponse, + type QuartrPaginatedDto, +} from '@/tools/quartr/types' +import { + buildQuartrListQuery, + buildQuartrUrl, + mapQuartrAudio, + normalizeQuartrIdList, + parseQuartrResponse, +} from '@/tools/quartr/utils' +import type { ToolConfig } from '@/tools/types' + +export const quartrListAudioTool: ToolConfig = { + id: 'quartr_list_audio', + name: 'Quartr List Audio', + description: + 'List archived event audio recordings from Quartr, filterable by company, event, and date range. Returns download (MPEG) and streaming (M3U8) URLs.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Quartr API key', + }, + companyIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of Quartr company IDs (e.g., "4742,128")', + }, + eventIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of Quartr event IDs (e.g., "128301")', + }, + tickers: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of company tickers (e.g., "AAPL,MSFT")', + }, + isins: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of ISINs (e.g., "US0378331005")', + }, + ciks: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of SEC CIKs (e.g., "0000320193")', + }, + countries: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of ISO 3166-1 alpha-2 country codes (e.g., "US,SE")', + }, + exchanges: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Comma-separated list of exchange symbols, without whitespace (e.g., "NasdaqGS")', + }, + startDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Only return audio dated on or after this ISO 8601 date (e.g., "2024-01-01")', + }, + endDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Only return audio dated on or before this ISO 8601 date (e.g., "2024-12-31")', + }, + expandEvent: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Include expanded event details on each audio recording', + }, + updatedAfter: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Only return data updated after this ISO 8601 date (e.g., "2024-01-01")', + }, + updatedBefore: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Only return data updated before this ISO 8601 date (e.g., "2024-12-31")', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of items to return in a single request (default: 10)', + }, + cursor: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from the previous response (nextCursor) for the next page', + }, + direction: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Sort direction by id: "asc" or "desc" (default: asc)', + }, + }, + + request: { + url: (params) => + buildQuartrUrl('/audio', { + ...buildQuartrListQuery(params), + companyIds: normalizeQuartrIdList(params.companyIds), + eventIds: normalizeQuartrIdList(params.eventIds), + startDate: params.startDate, + endDate: params.endDate, + expand: params.expandEvent === true ? 'event' : undefined, + }), + method: 'GET', + headers: (params) => ({ 'x-api-key': params.apiKey }), + }, + + transformResponse: async (response) => { + const data = await parseQuartrResponse>( + response, + 'list audio' + ) + + return { + success: true, + output: { + audioRecordings: (data.data ?? []).map(mapQuartrAudio), + nextCursor: data.pagination?.nextCursor ?? null, + }, + } + }, + + outputs: { + audioRecordings: { + type: 'array', + description: 'Audio recordings matching the filters', + items: { type: 'object', properties: QUARTR_AUDIO_OUTPUT_PROPERTIES }, + }, + nextCursor: { + type: 'number', + description: 'Cursor for fetching the next page of results (null when no more pages)', + optional: true, + }, + }, +} diff --git a/apps/sim/tools/quartr/list_companies.ts b/apps/sim/tools/quartr/list_companies.ts new file mode 100644 index 0000000000..9019692cd8 --- /dev/null +++ b/apps/sim/tools/quartr/list_companies.ts @@ -0,0 +1,148 @@ +import { + QUARTR_COMPANY_OUTPUT_PROPERTIES, + type QuartrCompanyDto, + type QuartrListCompaniesParams, + type QuartrListCompaniesResponse, + type QuartrPaginatedDto, +} from '@/tools/quartr/types' +import { + buildQuartrListQuery, + buildQuartrUrl, + mapQuartrCompany, + normalizeQuartrIdList, + parseQuartrResponse, +} from '@/tools/quartr/utils' +import type { ToolConfig } from '@/tools/types' + +export const quartrListCompaniesTool: ToolConfig< + QuartrListCompaniesParams, + QuartrListCompaniesResponse +> = { + id: 'quartr_list_companies', + name: 'Quartr List Companies', + description: + 'List companies covered by Quartr, filterable by ticker, ISIN, CIK, OpenFIGI, country, and exchange.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Quartr API key', + }, + tickers: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of company tickers (e.g., "AAPL,MSFT")', + }, + isins: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of ISINs (e.g., "US0378331005")', + }, + ciks: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of SEC CIKs (e.g., "0000320193")', + }, + countries: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of ISO 3166-1 alpha-2 country codes (e.g., "US,SE")', + }, + exchanges: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Comma-separated list of exchange symbols, without whitespace (e.g., "NasdaqGS")', + }, + companyIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of Quartr company IDs (e.g., "4742,128")', + }, + openfigis: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Comma-separated list of OpenFIGI codes (figi, compositeFigi, or shareClassFigi)', + }, + updatedAfter: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Only return data updated after this ISO 8601 date (e.g., "2024-01-01")', + }, + updatedBefore: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Only return data updated before this ISO 8601 date (e.g., "2024-12-31")', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of items to return in a single request (default: 10)', + }, + cursor: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from the previous response (nextCursor) for the next page', + }, + direction: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Sort direction by id: "asc" or "desc" (default: asc)', + }, + }, + + request: { + url: (params) => + buildQuartrUrl('/companies', { + ...buildQuartrListQuery(params), + ids: normalizeQuartrIdList(params.companyIds), + openfigis: normalizeQuartrIdList(params.openfigis), + }), + method: 'GET', + headers: (params) => ({ 'x-api-key': params.apiKey }), + }, + + transformResponse: async (response) => { + const data = await parseQuartrResponse>( + response, + 'list companies' + ) + + return { + success: true, + output: { + companies: (data.data ?? []).map(mapQuartrCompany), + nextCursor: data.pagination?.nextCursor ?? null, + }, + } + }, + + outputs: { + companies: { + type: 'array', + description: 'Companies matching the filters', + items: { type: 'object', properties: QUARTR_COMPANY_OUTPUT_PROPERTIES }, + }, + nextCursor: { + type: 'number', + description: 'Cursor for fetching the next page of results (null when no more pages)', + optional: true, + }, + }, +} diff --git a/apps/sim/tools/quartr/list_document_types.ts b/apps/sim/tools/quartr/list_document_types.ts new file mode 100644 index 0000000000..e2dfda6ef5 --- /dev/null +++ b/apps/sim/tools/quartr/list_document_types.ts @@ -0,0 +1,86 @@ +import { + QUARTR_DOCUMENT_TYPE_OUTPUT_PROPERTIES, + type QuartrDocumentTypeDto, + type QuartrListDocumentTypesParams, + type QuartrListDocumentTypesResponse, + type QuartrPaginatedDto, +} from '@/tools/quartr/types' +import { buildQuartrUrl, mapQuartrDocumentType, parseQuartrResponse } from '@/tools/quartr/utils' +import type { ToolConfig } from '@/tools/types' + +export const quartrListDocumentTypesTool: ToolConfig< + QuartrListDocumentTypesParams, + QuartrListDocumentTypesResponse +> = { + id: 'quartr_list_document_types', + name: 'Quartr List Document Types', + description: + 'List the document types available in Quartr (e.g., 10-Q quarterly reports), useful for filtering documents by type ID.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Quartr API key', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of items to return in a single request (default: 10)', + }, + cursor: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from the previous response (nextCursor) for the next page', + }, + direction: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Sort direction by id: "asc" or "desc" (default: asc)', + }, + }, + + request: { + url: (params) => + buildQuartrUrl('/document-types', { + limit: params.limit, + cursor: params.cursor, + direction: params.direction, + }), + method: 'GET', + headers: (params) => ({ 'x-api-key': params.apiKey }), + }, + + transformResponse: async (response) => { + const data = await parseQuartrResponse>( + response, + 'list document types' + ) + + return { + success: true, + output: { + documentTypes: (data.data ?? []).map(mapQuartrDocumentType), + nextCursor: data.pagination?.nextCursor ?? null, + }, + } + }, + + outputs: { + documentTypes: { + type: 'array', + description: 'Available document types', + items: { type: 'object', properties: QUARTR_DOCUMENT_TYPE_OUTPUT_PROPERTIES }, + }, + nextCursor: { + type: 'number', + description: 'Cursor for fetching the next page of results (null when no more pages)', + optional: true, + }, + }, +} diff --git a/apps/sim/tools/quartr/list_documents.ts b/apps/sim/tools/quartr/list_documents.ts new file mode 100644 index 0000000000..69d237fee1 --- /dev/null +++ b/apps/sim/tools/quartr/list_documents.ts @@ -0,0 +1,174 @@ +import { + QUARTR_DOCUMENT_OUTPUT_PROPERTIES, + type QuartrDocumentDto, + type QuartrListDocumentsParams, + type QuartrListDocumentsResponse, + type QuartrPaginatedDto, +} from '@/tools/quartr/types' +import { + buildQuartrDocumentListQuery, + buildQuartrUrl, + mapQuartrDocument, + parseQuartrResponse, +} from '@/tools/quartr/utils' +import type { ToolConfig } from '@/tools/types' + +export const quartrListDocumentsTool: ToolConfig< + QuartrListDocumentsParams, + QuartrListDocumentsResponse +> = { + id: 'quartr_list_documents', + name: 'Quartr List Documents', + description: + 'List documents of all kinds (reports, slide decks, and transcripts) from Quartr, filterable by company, event, document type, document group, and date range.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Quartr API key', + }, + companyIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of Quartr company IDs (e.g., "4742,128")', + }, + eventIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of Quartr event IDs (e.g., "128301")', + }, + tickers: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of company tickers (e.g., "AAPL,MSFT")', + }, + isins: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of ISINs (e.g., "US0378331005")', + }, + ciks: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of SEC CIKs (e.g., "0000320193")', + }, + countries: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of ISO 3166-1 alpha-2 country codes (e.g., "US,SE")', + }, + exchanges: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Comma-separated list of exchange symbols, without whitespace (e.g., "NasdaqGS")', + }, + documentTypeIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of document type IDs (e.g., "7,10")', + }, + documentGroupIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Comma-separated list of document group IDs: 1 = Earnings Release, 2 = Press Release, 3 = Interim Report, 4 = Annual Report, 5 = Proxy Statement, 6 = Registration Statement', + }, + startDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Only return documents dated on or after this ISO 8601 date (e.g., "2024-01-01")', + }, + endDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Only return documents dated on or before this ISO 8601 date (e.g., "2024-12-31")', + }, + expandEvent: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Include expanded event details on each document', + }, + updatedAfter: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Only return data updated after this ISO 8601 date (e.g., "2024-01-01")', + }, + updatedBefore: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Only return data updated before this ISO 8601 date (e.g., "2024-12-31")', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of items to return in a single request (default: 10)', + }, + cursor: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from the previous response (nextCursor) for the next page', + }, + direction: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Sort direction by id: "asc" or "desc" (default: asc)', + }, + }, + + request: { + url: (params) => buildQuartrUrl('/documents', buildQuartrDocumentListQuery(params)), + method: 'GET', + headers: (params) => ({ 'x-api-key': params.apiKey }), + }, + + transformResponse: async (response) => { + const data = await parseQuartrResponse>( + response, + 'list documents' + ) + + return { + success: true, + output: { + documents: (data.data ?? []).map(mapQuartrDocument), + nextCursor: data.pagination?.nextCursor ?? null, + }, + } + }, + + outputs: { + documents: { + type: 'array', + description: 'Documents matching the filters', + items: { type: 'object', properties: QUARTR_DOCUMENT_OUTPUT_PROPERTIES }, + }, + nextCursor: { + type: 'number', + description: 'Cursor for fetching the next page of results (null when no more pages)', + optional: true, + }, + }, +} diff --git a/apps/sim/tools/quartr/list_event_types.ts b/apps/sim/tools/quartr/list_event_types.ts new file mode 100644 index 0000000000..dbc425182b --- /dev/null +++ b/apps/sim/tools/quartr/list_event_types.ts @@ -0,0 +1,86 @@ +import { + QUARTR_EVENT_TYPE_OUTPUT_PROPERTIES, + type QuartrEventTypeDto, + type QuartrListEventTypesParams, + type QuartrListEventTypesResponse, + type QuartrPaginatedDto, +} from '@/tools/quartr/types' +import { buildQuartrUrl, mapQuartrEventType, parseQuartrResponse } from '@/tools/quartr/utils' +import type { ToolConfig } from '@/tools/types' + +export const quartrListEventTypesTool: ToolConfig< + QuartrListEventTypesParams, + QuartrListEventTypesResponse +> = { + id: 'quartr_list_event_types', + name: 'Quartr List Event Types', + description: + 'List the event types available in Quartr (e.g., earnings calls), useful for filtering events by type ID.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Quartr API key', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of items to return in a single request (default: 10)', + }, + cursor: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from the previous response (nextCursor) for the next page', + }, + direction: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Sort direction by id: "asc" or "desc" (default: asc)', + }, + }, + + request: { + url: (params) => + buildQuartrUrl('/event-types', { + limit: params.limit, + cursor: params.cursor, + direction: params.direction, + }), + method: 'GET', + headers: (params) => ({ 'x-api-key': params.apiKey }), + }, + + transformResponse: async (response) => { + const data = await parseQuartrResponse>( + response, + 'list event types' + ) + + return { + success: true, + output: { + eventTypes: (data.data ?? []).map(mapQuartrEventType), + nextCursor: data.pagination?.nextCursor ?? null, + }, + } + }, + + outputs: { + eventTypes: { + type: 'array', + description: 'Available event types', + items: { type: 'object', properties: QUARTR_EVENT_TYPE_OUTPUT_PROPERTIES }, + }, + nextCursor: { + type: 'number', + description: 'Cursor for fetching the next page of results (null when no more pages)', + optional: true, + }, + }, +} diff --git a/apps/sim/tools/quartr/list_events.ts b/apps/sim/tools/quartr/list_events.ts new file mode 100644 index 0000000000..33735060d2 --- /dev/null +++ b/apps/sim/tools/quartr/list_events.ts @@ -0,0 +1,165 @@ +import { + QUARTR_EVENT_OUTPUT_PROPERTIES, + type QuartrEventDto, + type QuartrListEventsParams, + type QuartrListEventsResponse, + type QuartrPaginatedDto, +} from '@/tools/quartr/types' +import { + buildQuartrListQuery, + buildQuartrUrl, + mapQuartrEvent, + normalizeQuartrIdList, + parseQuartrResponse, +} from '@/tools/quartr/utils' +import type { ToolConfig } from '@/tools/types' + +export const quartrListEventsTool: ToolConfig = { + id: 'quartr_list_events', + name: 'Quartr List Events', + description: + 'List corporate events (earnings calls, capital markets days, etc.) from Quartr, filterable by company, event type, and date range.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Quartr API key', + }, + companyIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of Quartr company IDs (e.g., "4742,128")', + }, + tickers: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of company tickers (e.g., "AAPL,MSFT")', + }, + isins: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of ISINs (e.g., "US0378331005")', + }, + ciks: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of SEC CIKs (e.g., "0000320193")', + }, + countries: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of ISO 3166-1 alpha-2 country codes (e.g., "US,SE")', + }, + exchanges: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Comma-separated list of exchange symbols, without whitespace (e.g., "NasdaqGS")', + }, + eventTypeIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of event type IDs (e.g., "26,27")', + }, + startDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Only return events on or after this ISO 8601 date (e.g., "2024-01-01")', + }, + endDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Only return events on or before this ISO 8601 date (e.g., "2024-12-31")', + }, + sortBy: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Field to sort by: "id" or "date" (default: id)', + }, + updatedAfter: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Only return data updated after this ISO 8601 date (e.g., "2024-01-01")', + }, + updatedBefore: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Only return data updated before this ISO 8601 date (e.g., "2024-12-31")', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of items to return in a single request (default: 10)', + }, + cursor: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from the previous response (nextCursor) for the next page', + }, + direction: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Sort direction by id: "asc" or "desc" (default: asc)', + }, + }, + + request: { + url: (params) => + buildQuartrUrl('/events', { + ...buildQuartrListQuery(params), + companyIds: normalizeQuartrIdList(params.companyIds), + typeIds: normalizeQuartrIdList(params.eventTypeIds), + startDate: params.startDate, + endDate: params.endDate, + sortBy: params.sortBy, + }), + method: 'GET', + headers: (params) => ({ 'x-api-key': params.apiKey }), + }, + + transformResponse: async (response) => { + const data = await parseQuartrResponse>( + response, + 'list events' + ) + + return { + success: true, + output: { + events: (data.data ?? []).map(mapQuartrEvent), + nextCursor: data.pagination?.nextCursor ?? null, + }, + } + }, + + outputs: { + events: { + type: 'array', + description: 'Events matching the filters', + items: { type: 'object', properties: QUARTR_EVENT_OUTPUT_PROPERTIES }, + }, + nextCursor: { + type: 'number', + description: 'Cursor for fetching the next page of results (null when no more pages)', + optional: true, + }, + }, +} diff --git a/apps/sim/tools/quartr/list_live_events.ts b/apps/sim/tools/quartr/list_live_events.ts new file mode 100644 index 0000000000..b688dcb678 --- /dev/null +++ b/apps/sim/tools/quartr/list_live_events.ts @@ -0,0 +1,176 @@ +import { + QUARTR_LIVE_EVENT_OUTPUT_PROPERTIES, + type QuartrListLiveEventsParams, + type QuartrListLiveEventsResponse, + type QuartrLiveEventDto, + type QuartrPaginatedDto, +} from '@/tools/quartr/types' +import { + buildQuartrListQuery, + buildQuartrUrl, + mapQuartrLiveEvent, + normalizeQuartrIdList, + parseQuartrResponse, +} from '@/tools/quartr/utils' +import type { ToolConfig } from '@/tools/types' + +export const quartrListLiveEventsTool: ToolConfig< + QuartrListLiveEventsParams, + QuartrListLiveEventsResponse +> = { + id: 'quartr_list_live_events', + name: 'Quartr List Live Events', + description: + 'List live and upcoming events from Quartr with live audio and transcript stream URLs, filterable by company, live state, and date range.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Quartr API key', + }, + companyIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of Quartr company IDs (e.g., "4742,128")', + }, + eventIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of Quartr event IDs (e.g., "128301")', + }, + tickers: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of company tickers (e.g., "AAPL,MSFT")', + }, + isins: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of ISINs (e.g., "US0378331005")', + }, + ciks: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of SEC CIKs (e.g., "0000320193")', + }, + countries: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of ISO 3166-1 alpha-2 country codes (e.g., "US,SE")', + }, + exchanges: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Comma-separated list of exchange symbols, without whitespace (e.g., "NasdaqGS")', + }, + states: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Comma-separated list of live states to filter by: notLive, willBeLive, live, liveFailedInterrupted, liveFailedNoAccess', + }, + startDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Only return events on or after this ISO 8601 date (e.g., "2024-01-01")', + }, + endDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Only return events on or before this ISO 8601 date (e.g., "2024-12-31")', + }, + transcriptVersion: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Version of the live transcript stream: "1.6" or "1.7" (default: 1.6)', + }, + updatedAfter: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Only return data updated after this ISO 8601 date (e.g., "2024-01-01")', + }, + updatedBefore: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Only return data updated before this ISO 8601 date (e.g., "2024-12-31")', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of items to return in a single request (default: 10)', + }, + cursor: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from the previous response (nextCursor) for the next page', + }, + direction: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Sort direction by id: "asc" or "desc" (default: asc)', + }, + }, + + request: { + url: (params) => + buildQuartrUrl('/live', { + ...buildQuartrListQuery(params), + companyIds: normalizeQuartrIdList(params.companyIds), + eventIds: normalizeQuartrIdList(params.eventIds), + states: normalizeQuartrIdList(params.states), + startDate: params.startDate, + endDate: params.endDate, + transcriptVersion: params.transcriptVersion, + }), + method: 'GET', + headers: (params) => ({ 'x-api-key': params.apiKey }), + }, + + transformResponse: async (response) => { + const data = await parseQuartrResponse>( + response, + 'list live events' + ) + + return { + success: true, + output: { + liveEvents: (data.data ?? []).map(mapQuartrLiveEvent), + nextCursor: data.pagination?.nextCursor ?? null, + }, + } + }, + + outputs: { + liveEvents: { + type: 'array', + description: 'Live events matching the filters', + items: { type: 'object', properties: QUARTR_LIVE_EVENT_OUTPUT_PROPERTIES }, + }, + nextCursor: { + type: 'number', + description: 'Cursor for fetching the next page of results (null when no more pages)', + optional: true, + }, + }, +} diff --git a/apps/sim/tools/quartr/list_reports.ts b/apps/sim/tools/quartr/list_reports.ts new file mode 100644 index 0000000000..5d105db508 --- /dev/null +++ b/apps/sim/tools/quartr/list_reports.ts @@ -0,0 +1,174 @@ +import { + QUARTR_DOCUMENT_OUTPUT_PROPERTIES, + type QuartrDocumentDto, + type QuartrListDocumentsParams, + type QuartrListReportsResponse, + type QuartrPaginatedDto, +} from '@/tools/quartr/types' +import { + buildQuartrDocumentListQuery, + buildQuartrUrl, + mapQuartrDocument, + parseQuartrResponse, +} from '@/tools/quartr/utils' +import type { ToolConfig } from '@/tools/types' + +export const quartrListReportsTool: ToolConfig< + QuartrListDocumentsParams, + QuartrListReportsResponse +> = { + id: 'quartr_list_reports', + name: 'Quartr List Reports', + description: + 'List filings and reports (10-K, 10-Q, earnings releases, etc.) from Quartr, filterable by company, event, document type, document group, and date range.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Quartr API key', + }, + companyIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of Quartr company IDs (e.g., "4742,128")', + }, + eventIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of Quartr event IDs (e.g., "128301")', + }, + tickers: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of company tickers (e.g., "AAPL,MSFT")', + }, + isins: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of ISINs (e.g., "US0378331005")', + }, + ciks: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of SEC CIKs (e.g., "0000320193")', + }, + countries: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of ISO 3166-1 alpha-2 country codes (e.g., "US,SE")', + }, + exchanges: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Comma-separated list of exchange symbols, without whitespace (e.g., "NasdaqGS")', + }, + documentTypeIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of document type IDs (e.g., "7,10")', + }, + documentGroupIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Comma-separated list of document group IDs: 1 = Earnings Release, 2 = Press Release, 3 = Interim Report, 4 = Annual Report, 5 = Proxy Statement, 6 = Registration Statement', + }, + startDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Only return documents dated on or after this ISO 8601 date (e.g., "2024-01-01")', + }, + endDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Only return documents dated on or before this ISO 8601 date (e.g., "2024-12-31")', + }, + expandEvent: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Include expanded event details on each document', + }, + updatedAfter: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Only return data updated after this ISO 8601 date (e.g., "2024-01-01")', + }, + updatedBefore: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Only return data updated before this ISO 8601 date (e.g., "2024-12-31")', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of items to return in a single request (default: 10)', + }, + cursor: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from the previous response (nextCursor) for the next page', + }, + direction: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Sort direction by id: "asc" or "desc" (default: asc)', + }, + }, + + request: { + url: (params) => buildQuartrUrl('/documents/reports', buildQuartrDocumentListQuery(params)), + method: 'GET', + headers: (params) => ({ 'x-api-key': params.apiKey }), + }, + + transformResponse: async (response) => { + const data = await parseQuartrResponse>( + response, + 'list reports' + ) + + return { + success: true, + output: { + reports: (data.data ?? []).map(mapQuartrDocument), + nextCursor: data.pagination?.nextCursor ?? null, + }, + } + }, + + outputs: { + reports: { + type: 'array', + description: 'Reports matching the filters', + items: { type: 'object', properties: QUARTR_DOCUMENT_OUTPUT_PROPERTIES }, + }, + nextCursor: { + type: 'number', + description: 'Cursor for fetching the next page of results (null when no more pages)', + optional: true, + }, + }, +} diff --git a/apps/sim/tools/quartr/list_slide_decks.ts b/apps/sim/tools/quartr/list_slide_decks.ts new file mode 100644 index 0000000000..c4628132ed --- /dev/null +++ b/apps/sim/tools/quartr/list_slide_decks.ts @@ -0,0 +1,174 @@ +import { + QUARTR_DOCUMENT_OUTPUT_PROPERTIES, + type QuartrDocumentDto, + type QuartrListDocumentsParams, + type QuartrListSlideDecksResponse, + type QuartrPaginatedDto, +} from '@/tools/quartr/types' +import { + buildQuartrDocumentListQuery, + buildQuartrUrl, + mapQuartrDocument, + parseQuartrResponse, +} from '@/tools/quartr/utils' +import type { ToolConfig } from '@/tools/types' + +export const quartrListSlideDecksTool: ToolConfig< + QuartrListDocumentsParams, + QuartrListSlideDecksResponse +> = { + id: 'quartr_list_slide_decks', + name: 'Quartr List Slide Decks', + description: + 'List slide presentations from Quartr, filterable by company, event, document type, document group, and date range.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Quartr API key', + }, + companyIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of Quartr company IDs (e.g., "4742,128")', + }, + eventIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of Quartr event IDs (e.g., "128301")', + }, + tickers: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of company tickers (e.g., "AAPL,MSFT")', + }, + isins: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of ISINs (e.g., "US0378331005")', + }, + ciks: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of SEC CIKs (e.g., "0000320193")', + }, + countries: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of ISO 3166-1 alpha-2 country codes (e.g., "US,SE")', + }, + exchanges: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Comma-separated list of exchange symbols, without whitespace (e.g., "NasdaqGS")', + }, + documentTypeIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of document type IDs (e.g., "7,10")', + }, + documentGroupIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Comma-separated list of document group IDs: 1 = Earnings Release, 2 = Press Release, 3 = Interim Report, 4 = Annual Report, 5 = Proxy Statement, 6 = Registration Statement', + }, + startDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Only return documents dated on or after this ISO 8601 date (e.g., "2024-01-01")', + }, + endDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Only return documents dated on or before this ISO 8601 date (e.g., "2024-12-31")', + }, + expandEvent: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Include expanded event details on each document', + }, + updatedAfter: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Only return data updated after this ISO 8601 date (e.g., "2024-01-01")', + }, + updatedBefore: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Only return data updated before this ISO 8601 date (e.g., "2024-12-31")', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of items to return in a single request (default: 10)', + }, + cursor: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from the previous response (nextCursor) for the next page', + }, + direction: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Sort direction by id: "asc" or "desc" (default: asc)', + }, + }, + + request: { + url: (params) => buildQuartrUrl('/documents/slides', buildQuartrDocumentListQuery(params)), + method: 'GET', + headers: (params) => ({ 'x-api-key': params.apiKey }), + }, + + transformResponse: async (response) => { + const data = await parseQuartrResponse>( + response, + 'list slide decks' + ) + + return { + success: true, + output: { + slideDecks: (data.data ?? []).map(mapQuartrDocument), + nextCursor: data.pagination?.nextCursor ?? null, + }, + } + }, + + outputs: { + slideDecks: { + type: 'array', + description: 'Slide decks matching the filters', + items: { type: 'object', properties: QUARTR_DOCUMENT_OUTPUT_PROPERTIES }, + }, + nextCursor: { + type: 'number', + description: 'Cursor for fetching the next page of results (null when no more pages)', + optional: true, + }, + }, +} diff --git a/apps/sim/tools/quartr/list_transcripts.ts b/apps/sim/tools/quartr/list_transcripts.ts new file mode 100644 index 0000000000..280cbadace --- /dev/null +++ b/apps/sim/tools/quartr/list_transcripts.ts @@ -0,0 +1,174 @@ +import { + QUARTR_DOCUMENT_OUTPUT_PROPERTIES, + type QuartrDocumentDto, + type QuartrListDocumentsParams, + type QuartrListTranscriptsResponse, + type QuartrPaginatedDto, +} from '@/tools/quartr/types' +import { + buildQuartrDocumentListQuery, + buildQuartrUrl, + mapQuartrDocument, + parseQuartrResponse, +} from '@/tools/quartr/utils' +import type { ToolConfig } from '@/tools/types' + +export const quartrListTranscriptsTool: ToolConfig< + QuartrListDocumentsParams, + QuartrListTranscriptsResponse +> = { + id: 'quartr_list_transcripts', + name: 'Quartr List Transcripts', + description: + 'List event transcripts from Quartr, filterable by company, event, document type, document group, and date range.', + version: '1.0.0', + + params: { + apiKey: { + type: 'string', + required: true, + visibility: 'user-only', + description: 'Quartr API key', + }, + companyIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of Quartr company IDs (e.g., "4742,128")', + }, + eventIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of Quartr event IDs (e.g., "128301")', + }, + tickers: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of company tickers (e.g., "AAPL,MSFT")', + }, + isins: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of ISINs (e.g., "US0378331005")', + }, + ciks: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of SEC CIKs (e.g., "0000320193")', + }, + countries: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of ISO 3166-1 alpha-2 country codes (e.g., "US,SE")', + }, + exchanges: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Comma-separated list of exchange symbols, without whitespace (e.g., "NasdaqGS")', + }, + documentTypeIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: 'Comma-separated list of document type IDs (e.g., "7,10")', + }, + documentGroupIds: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Comma-separated list of document group IDs: 1 = Earnings Release, 2 = Press Release, 3 = Interim Report, 4 = Annual Report, 5 = Proxy Statement, 6 = Registration Statement', + }, + startDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Only return documents dated on or after this ISO 8601 date (e.g., "2024-01-01")', + }, + endDate: { + type: 'string', + required: false, + visibility: 'user-or-llm', + description: + 'Only return documents dated on or before this ISO 8601 date (e.g., "2024-12-31")', + }, + expandEvent: { + type: 'boolean', + required: false, + visibility: 'user-or-llm', + description: 'Include expanded event details on each document', + }, + updatedAfter: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Only return data updated after this ISO 8601 date (e.g., "2024-01-01")', + }, + updatedBefore: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Only return data updated before this ISO 8601 date (e.g., "2024-12-31")', + }, + limit: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Maximum number of items to return in a single request (default: 10)', + }, + cursor: { + type: 'number', + required: false, + visibility: 'user-or-llm', + description: 'Pagination cursor from the previous response (nextCursor) for the next page', + }, + direction: { + type: 'string', + required: false, + visibility: 'user-only', + description: 'Sort direction by id: "asc" or "desc" (default: asc)', + }, + }, + + request: { + url: (params) => buildQuartrUrl('/documents/transcripts', buildQuartrDocumentListQuery(params)), + method: 'GET', + headers: (params) => ({ 'x-api-key': params.apiKey }), + }, + + transformResponse: async (response) => { + const data = await parseQuartrResponse>( + response, + 'list transcripts' + ) + + return { + success: true, + output: { + transcripts: (data.data ?? []).map(mapQuartrDocument), + nextCursor: data.pagination?.nextCursor ?? null, + }, + } + }, + + outputs: { + transcripts: { + type: 'array', + description: 'Transcripts matching the filters', + items: { type: 'object', properties: QUARTR_DOCUMENT_OUTPUT_PROPERTIES }, + }, + nextCursor: { + type: 'number', + description: 'Cursor for fetching the next page of results (null when no more pages)', + optional: true, + }, + }, +} diff --git a/apps/sim/tools/quartr/types.ts b/apps/sim/tools/quartr/types.ts new file mode 100644 index 0000000000..fddddde7fa --- /dev/null +++ b/apps/sim/tools/quartr/types.ts @@ -0,0 +1,675 @@ +import type { OutputProperty, ToolFileData, ToolResponse } from '@/tools/types' + +/** Raw ticker entry as returned by the Quartr API. */ +export interface QuartrTicker { + ticker: string + exchange: string +} + +/** Raw company shape as returned by the Quartr API (`CompanyDto`). */ +export interface QuartrCompanyDto { + id: number + name: string + displayName?: string + country: string + tickers?: QuartrTicker[] + isins?: string[] + cik?: string + openfigi?: string[] + backlinkUrl: string + createdAt: string + updatedAt: string +} + +/** Raw event shape as returned by the Quartr API (`EventDto`). */ +export interface QuartrEventDto { + id: number + companyId: number + title: string + date: string + typeId: number + fiscalYear?: number + fiscalPeriod?: string + language: string + backlinkUrl: string + createdAt: string + updatedAt: string +} + +/** Raw expanded event shape embedded on documents and audio (`ExpandedEventDto`). */ +export interface QuartrExpandedEventDto { + title?: string + typeId?: number + fiscalYear?: number + fiscalPeriod?: string + language?: string + date?: string +} + +/** Raw document shape as returned by the Quartr API (`DocumentDto`). */ +export interface QuartrDocumentDto { + id: number + companyId?: number + eventId?: number + typeId: number + fileUrl: string + createdAt: string + updatedAt: string + event?: QuartrExpandedEventDto +} + +/** Raw summary source as returned by the Quartr API (`SummarySource`). */ +export interface QuartrSummarySourceDto { + sourceId?: string + documentId: number + page?: number + timestamp?: number + typeId: number +} + +/** Raw summary shape as returned by the Quartr API (`SummaryDto`). */ +export interface QuartrSummaryDto { + id: number + summary: string + sources: QuartrSummarySourceDto[] + createdAt: string + updatedAt: string +} + +/** Raw audio metadata as returned by the Quartr API (`AudioMetadataDto`). */ +export interface QuartrAudioMetadataDto { + size?: string + duration?: number + encoding?: string + mimetype?: string +} + +/** Raw audio shape as returned by the Quartr API (`AudioDto`). */ +export interface QuartrAudioDto { + id: number + companyId: number + eventId: number + fileUrl?: string + streamUrl?: string + qna?: number + audioMetadata?: QuartrAudioMetadataDto + createdAt: string + updatedAt: string + event?: QuartrExpandedEventDto +} + +/** Raw live event shape as returned by the Quartr API (`LiveDto`). */ +export interface QuartrLiveEventDto { + id: number + eventId: number + companyId: number + date: string + wentLiveAt?: string + state?: string + audio?: string + transcript?: string + createdAt: string + updatedAt: string +} + +/** Raw event type shape as returned by the Quartr API (`EventTypeDto`). */ +export interface QuartrEventTypeDto { + id: number + name?: string + parent?: string + createdAt: string + updatedAt: string +} + +/** Raw document type shape as returned by the Quartr API (`DocumentTypeDto`). */ +export interface QuartrDocumentTypeDto { + id: number + name: string + description?: string + form?: string + category: string + documentGroupId?: number + createdAt: string + updatedAt: string +} + +/** Cursor pagination envelope returned by Quartr list endpoints. */ +export interface QuartrPaginationDto { + nextCursor: number | null +} + +/** Paginated list envelope returned by Quartr list endpoints. */ +export interface QuartrPaginatedDto { + data: T[] + pagination: QuartrPaginationDto +} + +/** Single-resource envelope returned by Quartr retrieve endpoints. */ +export interface QuartrSingleDto { + data: T +} + +/** Company with nullable optional fields, as emitted in tool outputs. */ +export interface QuartrCompany { + id: number + name: string + displayName: string | null + country: string + tickers: QuartrTicker[] + isins: string[] + cik: string | null + openfigi: string[] + backlinkUrl: string + createdAt: string + updatedAt: string +} + +/** Event with nullable optional fields, as emitted in tool outputs. */ +export interface QuartrEvent { + id: number + companyId: number + title: string + date: string + typeId: number + fiscalYear: number | null + fiscalPeriod: string | null + language: string + backlinkUrl: string + createdAt: string + updatedAt: string +} + +/** Expanded event with nullable optional fields, as emitted in tool outputs. */ +export interface QuartrExpandedEvent { + title: string | null + typeId: number | null + fiscalYear: number | null + fiscalPeriod: string | null + language: string | null + date: string | null +} + +/** Document with nullable optional fields, as emitted in tool outputs. */ +export interface QuartrDocument { + id: number + companyId: number | null + eventId: number | null + typeId: number + fileUrl: string + createdAt: string + updatedAt: string + event: QuartrExpandedEvent | null +} + +/** Summary source with nullable optional fields, as emitted in tool outputs. */ +export interface QuartrSummarySource { + sourceId: string | null + documentId: number + page: number | null + timestamp: number | null + typeId: number +} + +/** Audio metadata with nullable optional fields, as emitted in tool outputs. */ +export interface QuartrAudioMetadata { + size: string | null + duration: number | null + encoding: string | null + mimetype: string | null +} + +/** Audio recording with nullable optional fields, as emitted in tool outputs. */ +export interface QuartrAudio { + id: number + companyId: number + eventId: number + fileUrl: string | null + streamUrl: string | null + qna: number | null + audioMetadata: QuartrAudioMetadata | null + createdAt: string + updatedAt: string + event: QuartrExpandedEvent | null +} + +/** Live event with nullable optional fields, as emitted in tool outputs. */ +export interface QuartrLiveEvent { + id: number + eventId: number + companyId: number + date: string + wentLiveAt: string | null + state: string | null + audio: string | null + transcript: string | null + createdAt: string + updatedAt: string +} + +/** Event type with nullable optional fields, as emitted in tool outputs. */ +export interface QuartrEventType { + id: number + name: string | null + parent: string | null + createdAt: string + updatedAt: string +} + +/** Document type with nullable optional fields, as emitted in tool outputs. */ +export interface QuartrDocumentType { + id: number + name: string + description: string | null + form: string | null + category: string + documentGroupId: number | null + createdAt: string + updatedAt: string +} + +/** Cursor pagination parameters shared by all Quartr list tools. */ +export interface QuartrPaginationParams { + limit?: number | string + cursor?: number | string + direction?: string +} + +/** `updatedAt` range filters shared by Quartr list tools. */ +export interface QuartrUpdatedRangeParams { + updatedAfter?: string + updatedBefore?: string +} + +/** Company identifier filters shared by Quartr list tools. */ +export interface QuartrCompanyFilterParams { + tickers?: string + isins?: string + ciks?: string + countries?: string + exchanges?: string +} + +export interface QuartrListCompaniesParams + extends QuartrCompanyFilterParams, + QuartrPaginationParams, + QuartrUpdatedRangeParams { + apiKey: string + companyIds?: string + openfigis?: string +} + +export interface QuartrGetCompanyParams { + apiKey: string + companyId: number | string +} + +export interface QuartrListEventsParams + extends QuartrCompanyFilterParams, + QuartrPaginationParams, + QuartrUpdatedRangeParams { + apiKey: string + companyIds?: string + eventTypeIds?: string + startDate?: string + endDate?: string + sortBy?: string +} + +export interface QuartrGetEventParams { + apiKey: string + eventId: number | string +} + +export interface QuartrGetEventSummaryParams { + apiKey: string + eventId: number | string + summaryLength?: string + plainSummary?: boolean +} + +export interface QuartrListEventTypesParams extends QuartrPaginationParams { + apiKey: string +} + +export interface QuartrListDocumentTypesParams extends QuartrPaginationParams { + apiKey: string +} + +/** Filters shared by the documents, reports, slide decks, and transcripts list tools. */ +export interface QuartrListDocumentsParams + extends QuartrCompanyFilterParams, + QuartrPaginationParams, + QuartrUpdatedRangeParams { + apiKey: string + companyIds?: string + eventIds?: string + documentTypeIds?: string + documentGroupIds?: string + startDate?: string + endDate?: string + expandEvent?: boolean +} + +export interface QuartrGetReportParams { + apiKey: string + reportId: number | string +} + +export interface QuartrGetSlideDeckParams { + apiKey: string + slideDeckId: number | string +} + +export interface QuartrGetTranscriptParams { + apiKey: string + transcriptId: number | string +} + +export interface QuartrListAudioParams + extends QuartrCompanyFilterParams, + QuartrPaginationParams, + QuartrUpdatedRangeParams { + apiKey: string + companyIds?: string + eventIds?: string + startDate?: string + endDate?: string + expandEvent?: boolean +} + +export interface QuartrGetAudioParams { + apiKey: string + audioId: number | string +} + +export interface QuartrListLiveEventsParams + extends QuartrCompanyFilterParams, + QuartrPaginationParams, + QuartrUpdatedRangeParams { + apiKey: string + companyIds?: string + eventIds?: string + states?: string + startDate?: string + endDate?: string + transcriptVersion?: string +} + +export interface QuartrListCompaniesResponse extends ToolResponse { + output: { + companies: QuartrCompany[] + nextCursor: number | null + } +} + +export interface QuartrGetCompanyResponse extends ToolResponse { + output: { + company: QuartrCompany + } +} + +export interface QuartrListEventsResponse extends ToolResponse { + output: { + events: QuartrEvent[] + nextCursor: number | null + } +} + +export interface QuartrGetEventResponse extends ToolResponse { + output: { + event: QuartrEvent + } +} + +export interface QuartrGetEventSummaryResponse extends ToolResponse { + output: { + summary: string + sources: QuartrSummarySource[] + summaryId: number + summaryCreatedAt: string + summaryUpdatedAt: string + } +} + +export interface QuartrListEventTypesResponse extends ToolResponse { + output: { + eventTypes: QuartrEventType[] + nextCursor: number | null + } +} + +export interface QuartrListDocumentTypesResponse extends ToolResponse { + output: { + documentTypes: QuartrDocumentType[] + nextCursor: number | null + } +} + +export interface QuartrListDocumentsResponse extends ToolResponse { + output: { + documents: QuartrDocument[] + nextCursor: number | null + } +} + +export interface QuartrListReportsResponse extends ToolResponse { + output: { + reports: QuartrDocument[] + nextCursor: number | null + } +} + +export interface QuartrListSlideDecksResponse extends ToolResponse { + output: { + slideDecks: QuartrDocument[] + nextCursor: number | null + } +} + +export interface QuartrListTranscriptsResponse extends ToolResponse { + output: { + transcripts: QuartrDocument[] + nextCursor: number | null + } +} + +export interface QuartrGetDocumentFileResponse extends ToolResponse { + output: { + document: QuartrDocument + fileUrl: string + file: ToolFileData + } +} + +export interface QuartrListAudioResponse extends ToolResponse { + output: { + audioRecordings: QuartrAudio[] + nextCursor: number | null + } +} + +export interface QuartrGetAudioResponse extends ToolResponse { + output: { + audio: QuartrAudio + } +} + +export interface QuartrListLiveEventsResponse extends ToolResponse { + output: { + liveEvents: QuartrLiveEvent[] + nextCursor: number | null + } +} + +export const QUARTR_TICKER_OUTPUT_PROPERTIES = { + ticker: { type: 'string', description: 'Ticker symbol' }, + exchange: { type: 'string', description: 'Exchange symbol' }, +} as const satisfies Record + +export const QUARTR_COMPANY_OUTPUT_PROPERTIES = { + id: { type: 'number', description: 'Quartr company ID' }, + name: { type: 'string', description: 'Legal company name' }, + displayName: { type: 'string', description: 'Display name', nullable: true }, + country: { type: 'string', description: 'ISO 3166-1 alpha-2 country code' }, + tickers: { + type: 'array', + description: 'Ticker listings for the company', + items: { type: 'object', properties: QUARTR_TICKER_OUTPUT_PROPERTIES }, + }, + isins: { type: 'array', description: 'ISINs for the company', items: { type: 'string' } }, + cik: { type: 'string', description: 'SEC Central Index Key', nullable: true }, + openfigi: { + type: 'array', + description: 'OpenFIGI share class identifiers', + items: { type: 'string' }, + }, + backlinkUrl: { type: 'string', description: 'Quartr backlink URL for the company' }, + createdAt: { type: 'string', description: 'Creation timestamp (ISO 8601)' }, + updatedAt: { type: 'string', description: 'Last update timestamp (ISO 8601)' }, +} as const satisfies Record + +export const QUARTR_EVENT_OUTPUT_PROPERTIES = { + id: { type: 'number', description: 'Quartr event ID' }, + companyId: { type: 'number', description: 'Quartr company ID' }, + title: { type: 'string', description: 'Event title (e.g., "Q1 2024")' }, + date: { type: 'string', description: 'Event date (ISO 8601)' }, + typeId: { type: 'number', description: 'Event type ID' }, + fiscalYear: { type: 'number', description: 'Fiscal year', nullable: true }, + fiscalPeriod: { type: 'string', description: 'Fiscal period (e.g., "Q1")', nullable: true }, + language: { type: 'string', description: 'Event language code' }, + backlinkUrl: { type: 'string', description: 'Quartr backlink URL for the event' }, + createdAt: { type: 'string', description: 'Creation timestamp (ISO 8601)' }, + updatedAt: { type: 'string', description: 'Last update timestamp (ISO 8601)' }, +} as const satisfies Record + +export const QUARTR_EXPANDED_EVENT_OUTPUT_PROPERTIES = { + title: { type: 'string', description: 'Event title', nullable: true }, + typeId: { type: 'number', description: 'Event type ID', nullable: true }, + fiscalYear: { type: 'number', description: 'Fiscal year', nullable: true }, + fiscalPeriod: { type: 'string', description: 'Fiscal period (e.g., "Q1")', nullable: true }, + language: { type: 'string', description: 'Event language code', nullable: true }, + date: { type: 'string', description: 'Event date (ISO 8601)', nullable: true }, +} as const satisfies Record + +export const QUARTR_DOCUMENT_OUTPUT_PROPERTIES = { + id: { type: 'number', description: 'Quartr document ID' }, + companyId: { type: 'number', description: 'Quartr company ID', nullable: true }, + eventId: { type: 'number', description: 'Quartr event ID', nullable: true }, + typeId: { type: 'number', description: 'Document type ID' }, + fileUrl: { type: 'string', description: 'URL of the document file' }, + createdAt: { type: 'string', description: 'Creation timestamp (ISO 8601)' }, + updatedAt: { type: 'string', description: 'Last update timestamp (ISO 8601)' }, + event: { + type: 'object', + description: 'Expanded event details (present when event expansion is requested)', + nullable: true, + properties: QUARTR_EXPANDED_EVENT_OUTPUT_PROPERTIES, + }, +} as const satisfies Record + +export const QUARTR_SUMMARY_SOURCE_OUTPUT_PROPERTIES = { + sourceId: { + type: 'string', + description: 'ID linking the source document to tags embedded in the summary', + nullable: true, + }, + documentId: { type: 'number', description: 'Quartr document ID of the source' }, + page: { + type: 'number', + description: 'Page number or timestamp in seconds depending on the document type', + nullable: true, + }, + timestamp: { type: 'number', description: 'Timestamp in seconds', nullable: true }, + typeId: { type: 'number', description: 'Document type ID of the source' }, +} as const satisfies Record + +export const QUARTR_AUDIO_METADATA_OUTPUT_PROPERTIES = { + size: { type: 'string', description: 'File size (e.g., "200.00 MB")', nullable: true }, + duration: { type: 'number', description: 'Duration in seconds', nullable: true }, + encoding: { type: 'string', description: 'Audio encoding', nullable: true }, + mimetype: { type: 'string', description: 'Audio MIME type', nullable: true }, +} as const satisfies Record + +export const QUARTR_AUDIO_OUTPUT_PROPERTIES = { + id: { type: 'number', description: 'Quartr audio ID' }, + companyId: { type: 'number', description: 'Quartr company ID' }, + eventId: { type: 'number', description: 'Quartr event ID' }, + fileUrl: { type: 'string', description: 'Download URL of the audio file (MPEG)', nullable: true }, + streamUrl: { + type: 'string', + description: 'Streaming URL of the audio (M3U8)', + nullable: true, + }, + qna: { + type: 'number', + description: 'Timestamp in seconds where the Q&A section starts', + nullable: true, + }, + audioMetadata: { + type: 'object', + description: 'Audio file metadata', + nullable: true, + properties: QUARTR_AUDIO_METADATA_OUTPUT_PROPERTIES, + }, + createdAt: { type: 'string', description: 'Creation timestamp (ISO 8601)' }, + updatedAt: { type: 'string', description: 'Last update timestamp (ISO 8601)' }, + event: { + type: 'object', + description: 'Expanded event details (present when event expansion is requested)', + nullable: true, + properties: QUARTR_EXPANDED_EVENT_OUTPUT_PROPERTIES, + }, +} as const satisfies Record + +export const QUARTR_LIVE_EVENT_OUTPUT_PROPERTIES = { + id: { type: 'number', description: 'Quartr live event ID' }, + eventId: { type: 'number', description: 'Quartr event ID' }, + companyId: { type: 'number', description: 'Quartr company ID' }, + date: { type: 'string', description: 'Scheduled event date (ISO 8601)' }, + wentLiveAt: { + type: 'string', + description: 'Timestamp when the event went live (ISO 8601)', + nullable: true, + }, + state: { + type: 'string', + description: + 'Live state (notLive, willBeLive, live, liveFailedInterrupted, liveFailedNoAccess, recordingAvailable)', + nullable: true, + }, + audio: { + type: 'string', + description: 'URL of the live audio stream or recording', + nullable: true, + }, + transcript: { + type: 'string', + description: 'URL of the live transcript stream (JSON Lines)', + nullable: true, + }, + createdAt: { type: 'string', description: 'Creation timestamp (ISO 8601)' }, + updatedAt: { type: 'string', description: 'Last update timestamp (ISO 8601)' }, +} as const satisfies Record + +export const QUARTR_EVENT_TYPE_OUTPUT_PROPERTIES = { + id: { type: 'number', description: 'Event type ID' }, + name: { type: 'string', description: 'Event type name (e.g., "Q1")', nullable: true }, + parent: { + type: 'string', + description: 'Parent event type name (e.g., "Earnings call")', + nullable: true, + }, + createdAt: { type: 'string', description: 'Creation timestamp (ISO 8601)' }, + updatedAt: { type: 'string', description: 'Last update timestamp (ISO 8601)' }, +} as const satisfies Record + +export const QUARTR_DOCUMENT_TYPE_OUTPUT_PROPERTIES = { + id: { type: 'number', description: 'Document type ID' }, + name: { type: 'string', description: 'Document type name (e.g., "Quarterly Report")' }, + description: { type: 'string', description: 'Document type description', nullable: true }, + form: { type: 'string', description: 'Filing form (e.g., "10-Q")', nullable: true }, + category: { type: 'string', description: 'Document category (e.g., "Report")' }, + documentGroupId: { type: 'number', description: 'Document group ID', nullable: true }, + createdAt: { type: 'string', description: 'Creation timestamp (ISO 8601)' }, + updatedAt: { type: 'string', description: 'Last update timestamp (ISO 8601)' }, +} as const satisfies Record diff --git a/apps/sim/tools/quartr/utils.ts b/apps/sim/tools/quartr/utils.ts new file mode 100644 index 0000000000..2d2519b67d --- /dev/null +++ b/apps/sim/tools/quartr/utils.ts @@ -0,0 +1,259 @@ +import type { + QuartrAudio, + QuartrAudioDto, + QuartrCompany, + QuartrCompanyDto, + QuartrCompanyFilterParams, + QuartrDocument, + QuartrDocumentDto, + QuartrDocumentType, + QuartrDocumentTypeDto, + QuartrEvent, + QuartrEventDto, + QuartrEventType, + QuartrEventTypeDto, + QuartrExpandedEvent, + QuartrExpandedEventDto, + QuartrListDocumentsParams, + QuartrLiveEvent, + QuartrLiveEventDto, + QuartrPaginationParams, + QuartrSummarySource, + QuartrSummarySourceDto, + QuartrUpdatedRangeParams, +} from '@/tools/quartr/types' + +export const QUARTR_API_BASE_URL = 'https://api.quartr.com/public/v3' + +/** + * Normalizes a comma-separated list value by trimming whitespace around each + * entry, since the Quartr API expects lists without blank spaces. + */ +function normalizeCommaList(value: string | undefined): string | undefined { + if (!value) return undefined + const normalized = value + .split(',') + .map((entry) => entry.trim()) + .filter(Boolean) + .join(',') + return normalized || undefined +} + +/** + * Builds a Quartr API URL, appending only query parameters that have a value. + */ +export function buildQuartrUrl( + path: string, + query?: Record +): string { + const url = new URL(`${QUARTR_API_BASE_URL}${path}`) + if (query) { + for (const [key, value] of Object.entries(query)) { + if (value === undefined || value === '') continue + url.searchParams.set(key, String(value)) + } + } + return url.toString() +} + +/** + * Builds the query parameters shared by all Quartr list tools: company + * identifier filters, pagination, and updatedAt range filters. + */ +export function buildQuartrListQuery( + params: QuartrCompanyFilterParams & QuartrPaginationParams & QuartrUpdatedRangeParams +): Record { + return { + tickers: normalizeCommaList(params.tickers), + isins: normalizeCommaList(params.isins), + ciks: normalizeCommaList(params.ciks), + countries: normalizeCommaList(params.countries), + exchanges: normalizeCommaList(params.exchanges), + limit: params.limit, + cursor: params.cursor, + direction: params.direction, + updatedAfter: params.updatedAfter, + updatedBefore: params.updatedBefore, + } +} + +/** + * Normalizes a comma-separated identifier list for query usage. + */ +export function normalizeQuartrIdList(value: string | undefined): string | undefined { + return normalizeCommaList(value) +} + +/** + * Builds the query parameters shared by the documents, reports, slide decks, + * and transcripts list tools. + */ +export function buildQuartrDocumentListQuery( + params: QuartrListDocumentsParams +): Record { + return { + ...buildQuartrListQuery(params), + companyIds: normalizeCommaList(params.companyIds), + eventIds: normalizeCommaList(params.eventIds), + typeIds: normalizeCommaList(params.documentTypeIds), + documentGroupIds: normalizeCommaList(params.documentGroupIds), + startDate: params.startDate, + endDate: params.endDate, + expand: params.expandEvent === true ? 'event' : undefined, + } +} + +/** + * Parses a Quartr API response, throwing a descriptive error for failures. + */ +export async function parseQuartrResponse(response: Response, operation: string): Promise { + const text = await response.text() + let data: unknown + try { + data = JSON.parse(text) + } catch { + data = undefined + } + + if (!response.ok) { + const body = data as { message?: string | string[]; error?: string } | undefined + const rawMessage = body?.message ?? body?.error ?? `HTTP ${response.status}` + const message = Array.isArray(rawMessage) ? rawMessage.join(', ') : rawMessage + throw new Error(`Quartr ${operation} failed (${response.status}): ${message}`) + } + + if (data === undefined) { + throw new Error(`Quartr ${operation} returned an invalid JSON response`) + } + + return data as T +} + +export function mapQuartrCompany(dto: QuartrCompanyDto): QuartrCompany { + return { + id: dto.id, + name: dto.name, + displayName: dto.displayName ?? null, + country: dto.country, + tickers: dto.tickers ?? [], + isins: dto.isins ?? [], + cik: dto.cik ?? null, + openfigi: dto.openfigi ?? [], + backlinkUrl: dto.backlinkUrl, + createdAt: dto.createdAt, + updatedAt: dto.updatedAt, + } +} + +export function mapQuartrEvent(dto: QuartrEventDto): QuartrEvent { + return { + id: dto.id, + companyId: dto.companyId, + title: dto.title, + date: dto.date, + typeId: dto.typeId, + fiscalYear: dto.fiscalYear ?? null, + fiscalPeriod: dto.fiscalPeriod ?? null, + language: dto.language, + backlinkUrl: dto.backlinkUrl, + createdAt: dto.createdAt, + updatedAt: dto.updatedAt, + } +} + +export function mapQuartrExpandedEvent( + dto: QuartrExpandedEventDto | undefined +): QuartrExpandedEvent | null { + if (!dto) return null + return { + title: dto.title ?? null, + typeId: dto.typeId ?? null, + fiscalYear: dto.fiscalYear ?? null, + fiscalPeriod: dto.fiscalPeriod ?? null, + language: dto.language ?? null, + date: dto.date ?? null, + } +} + +export function mapQuartrDocument(dto: QuartrDocumentDto): QuartrDocument { + return { + id: dto.id, + companyId: dto.companyId ?? null, + eventId: dto.eventId ?? null, + typeId: dto.typeId, + fileUrl: dto.fileUrl, + createdAt: dto.createdAt, + updatedAt: dto.updatedAt, + event: mapQuartrExpandedEvent(dto.event), + } +} + +export function mapQuartrSummarySource(dto: QuartrSummarySourceDto): QuartrSummarySource { + return { + sourceId: dto.sourceId ?? null, + documentId: dto.documentId, + page: dto.page ?? null, + timestamp: dto.timestamp ?? null, + typeId: dto.typeId, + } +} + +export function mapQuartrAudio(dto: QuartrAudioDto): QuartrAudio { + return { + id: dto.id, + companyId: dto.companyId, + eventId: dto.eventId, + fileUrl: dto.fileUrl ?? null, + streamUrl: dto.streamUrl ?? null, + qna: dto.qna ?? null, + audioMetadata: dto.audioMetadata + ? { + size: dto.audioMetadata.size ?? null, + duration: dto.audioMetadata.duration ?? null, + encoding: dto.audioMetadata.encoding ?? null, + mimetype: dto.audioMetadata.mimetype ?? null, + } + : null, + createdAt: dto.createdAt, + updatedAt: dto.updatedAt, + event: mapQuartrExpandedEvent(dto.event), + } +} + +export function mapQuartrLiveEvent(dto: QuartrLiveEventDto): QuartrLiveEvent { + return { + id: dto.id, + eventId: dto.eventId, + companyId: dto.companyId, + date: dto.date, + wentLiveAt: dto.wentLiveAt ?? null, + state: dto.state ?? null, + audio: dto.audio ?? null, + transcript: dto.transcript ?? null, + createdAt: dto.createdAt, + updatedAt: dto.updatedAt, + } +} + +export function mapQuartrEventType(dto: QuartrEventTypeDto): QuartrEventType { + return { + id: dto.id, + name: dto.name ?? null, + parent: dto.parent ?? null, + createdAt: dto.createdAt, + updatedAt: dto.updatedAt, + } +} + +export function mapQuartrDocumentType(dto: QuartrDocumentTypeDto): QuartrDocumentType { + return { + id: dto.id, + name: dto.name, + description: dto.description ?? null, + form: dto.form ?? null, + category: dto.category, + documentGroupId: dto.documentGroupId ?? null, + createdAt: dto.createdAt, + updatedAt: dto.updatedAt, + } +} diff --git a/apps/sim/tools/registry.ts b/apps/sim/tools/registry.ts index 0529151f12..7040ec8d73 100644 --- a/apps/sim/tools/registry.ts +++ b/apps/sim/tools/registry.ts @@ -2395,6 +2395,25 @@ import { } from '@/tools/prospeo' import { pulseParserTool, pulseParserV2Tool } from '@/tools/pulse' import { qdrantFetchTool, qdrantSearchTool, qdrantUpsertTool } from '@/tools/qdrant' +import { + quartrGetAudioTool, + quartrGetCompanyTool, + quartrGetEventSummaryTool, + quartrGetEventTool, + quartrGetReportTool, + quartrGetSlideDeckTool, + quartrGetTranscriptTool, + quartrListAudioTool, + quartrListCompaniesTool, + quartrListDocumentsTool, + quartrListDocumentTypesTool, + quartrListEventsTool, + quartrListEventTypesTool, + quartrListLiveEventsTool, + quartrListReportsTool, + quartrListSlideDecksTool, + quartrListTranscriptsTool, +} from '@/tools/quartr' import { quiverImageToSvgTool, quiverListModelsTool, quiverTextToSvgTool } from '@/tools/quiver' import { railwayCreateEnvironmentTool, @@ -5283,6 +5302,23 @@ export const tools: Record = { profound_visibility_report: profoundVisibilityReportTool, pulse_parser: pulseParserTool, pulse_parser_v2: pulseParserV2Tool, + quartr_list_companies: quartrListCompaniesTool, + quartr_get_company: quartrGetCompanyTool, + quartr_list_events: quartrListEventsTool, + quartr_get_event: quartrGetEventTool, + quartr_get_event_summary: quartrGetEventSummaryTool, + quartr_list_event_types: quartrListEventTypesTool, + quartr_list_documents: quartrListDocumentsTool, + quartr_list_document_types: quartrListDocumentTypesTool, + quartr_list_reports: quartrListReportsTool, + quartr_get_report: quartrGetReportTool, + quartr_list_slide_decks: quartrListSlideDecksTool, + quartr_get_slide_deck: quartrGetSlideDeckTool, + quartr_list_transcripts: quartrListTranscriptsTool, + quartr_get_transcript: quartrGetTranscriptTool, + quartr_list_audio: quartrListAudioTool, + quartr_get_audio: quartrGetAudioTool, + quartr_list_live_events: quartrListLiveEventsTool, quiver_image_to_svg: quiverImageToSvgTool, quiver_list_models: quiverListModelsTool, quiver_text_to_svg: quiverTextToSvgTool, From d56689a61a7aa0330d33c5e4c53f847a658f23e3 Mon Sep 17 00:00:00 2001 From: waleed Date: Thu, 11 Jun 2026 18:13:50 -0700 Subject: [PATCH 2/2] =?UTF-8?q?fix(quartr):=20address=20review=20findings?= =?UTF-8?q?=20=E2=80=94=20null-safe=20query=20building,=20string=20boolean?= =?UTF-8?q?=20toggles,=20accurate=20descriptions,=20NestJS=20validation=20?= =?UTF-8?q?error=20extractor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../content/docs/en/integrations/quartr.mdx | 28 ++++----- apps/sim/blocks/blocks/quartr.ts | 9 ++- apps/sim/tools/error-extractors.ts | 26 ++++++++ apps/sim/tools/quartr/get_event_summary.ts | 12 +++- apps/sim/tools/quartr/list_audio.ts | 11 ++-- apps/sim/tools/quartr/list_companies.ts | 8 +-- apps/sim/tools/quartr/list_document_types.ts | 2 +- apps/sim/tools/quartr/list_documents.ts | 2 +- apps/sim/tools/quartr/list_event_types.ts | 2 +- apps/sim/tools/quartr/list_events.ts | 10 +-- apps/sim/tools/quartr/list_live_events.ts | 12 ++-- apps/sim/tools/quartr/list_reports.ts | 2 +- apps/sim/tools/quartr/list_slide_decks.ts | 2 +- apps/sim/tools/quartr/list_transcripts.ts | 2 +- apps/sim/tools/quartr/types.ts | 8 +-- apps/sim/tools/quartr/utils.ts | 63 ++++++++++++------- 16 files changed, 125 insertions(+), 74 deletions(-) diff --git a/apps/docs/content/docs/en/integrations/quartr.mdx b/apps/docs/content/docs/en/integrations/quartr.mdx index bdc71b0926..a536bfedc5 100644 --- a/apps/docs/content/docs/en/integrations/quartr.mdx +++ b/apps/docs/content/docs/en/integrations/quartr.mdx @@ -55,7 +55,7 @@ List companies covered by Quartr, filterable by ticker, ISIN, CIK, OpenFIGI, cou | `openfigis` | string | No | Comma-separated list of OpenFIGI codes \(figi, compositeFigi, or shareClassFigi\) | | `updatedAfter` | string | No | Only return data updated after this ISO 8601 date \(e.g., "2024-01-01"\) | | `updatedBefore` | string | No | Only return data updated before this ISO 8601 date \(e.g., "2024-12-31"\) | -| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10, max: 500\) | | `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | | `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | @@ -130,9 +130,9 @@ List corporate events (earnings calls, capital markets days, etc.) from Quartr, | `sortBy` | string | No | Field to sort by: "id" or "date" \(default: id\) | | `updatedAfter` | string | No | Only return data updated after this ISO 8601 date \(e.g., "2024-01-01"\) | | `updatedBefore` | string | No | Only return data updated before this ISO 8601 date \(e.g., "2024-12-31"\) | -| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10, max: 500\) | | `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | -| `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | +| `direction` | string | No | Sort direction applied to the sortBy field: "asc" or "desc" \(default: asc\) | #### Output @@ -197,7 +197,7 @@ Retrieve the AI-generated summary of a corporate event from Quartr, with selecta | Parameter | Type | Description | | --------- | ---- | ----------- | -| `summary` | string | AI-generated event summary in Markdown | +| `summary` | string | AI-generated event summary in Markdown \(includes embedded document source tags unless a plain-text summary is requested\) | | `sources` | array | Source documents referenced by the summary | | ↳ `sourceId` | string | ID linking the source document to tags embedded in the summary | | ↳ `documentId` | number | Quartr document ID of the source | @@ -217,7 +217,7 @@ List the event types available in Quartr (e.g., earnings calls), useful for filt | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `apiKey` | string | Yes | Quartr API key | -| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10, max: 500\) | | `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | | `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | @@ -256,7 +256,7 @@ List documents of all kinds (reports, slide decks, and transcripts) from Quartr, | `expandEvent` | boolean | No | Include expanded event details on each document | | `updatedAfter` | string | No | Only return data updated after this ISO 8601 date \(e.g., "2024-01-01"\) | | `updatedBefore` | string | No | Only return data updated before this ISO 8601 date \(e.g., "2024-12-31"\) | -| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10, max: 500\) | | `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | | `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | @@ -290,7 +290,7 @@ List the document types available in Quartr (e.g., 10-Q quarterly reports), usef | Parameter | Type | Required | Description | | --------- | ---- | -------- | ----------- | | `apiKey` | string | Yes | Quartr API key | -| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10, max: 500\) | | `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | | `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | @@ -332,7 +332,7 @@ List filings and reports (10-K, 10-Q, earnings releases, etc.) from Quartr, filt | `expandEvent` | boolean | No | Include expanded event details on each document | | `updatedAfter` | string | No | Only return data updated after this ISO 8601 date \(e.g., "2024-01-01"\) | | `updatedBefore` | string | No | Only return data updated before this ISO 8601 date \(e.g., "2024-12-31"\) | -| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10, max: 500\) | | `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | | `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | @@ -413,7 +413,7 @@ List slide presentations from Quartr, filterable by company, event, document typ | `expandEvent` | boolean | No | Include expanded event details on each document | | `updatedAfter` | string | No | Only return data updated after this ISO 8601 date \(e.g., "2024-01-01"\) | | `updatedBefore` | string | No | Only return data updated before this ISO 8601 date \(e.g., "2024-12-31"\) | -| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10, max: 500\) | | `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | | `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | @@ -494,7 +494,7 @@ List event transcripts from Quartr, filterable by company, event, document type, | `expandEvent` | boolean | No | Include expanded event details on each document | | `updatedAfter` | string | No | Only return data updated after this ISO 8601 date \(e.g., "2024-01-01"\) | | `updatedBefore` | string | No | Only return data updated before this ISO 8601 date \(e.g., "2024-12-31"\) | -| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10, max: 500\) | | `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | | `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | @@ -573,7 +573,7 @@ List archived event audio recordings from Quartr, filterable by company, event, | `expandEvent` | boolean | No | Include expanded event details on each audio recording | | `updatedAfter` | string | No | Only return data updated after this ISO 8601 date \(e.g., "2024-01-01"\) | | `updatedBefore` | string | No | Only return data updated before this ISO 8601 date \(e.g., "2024-12-31"\) | -| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10, max: 500\) | | `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | | `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | @@ -657,13 +657,13 @@ List live and upcoming events from Quartr with live audio and transcript stream | `ciks` | string | No | Comma-separated list of SEC CIKs \(e.g., "0000320193"\) | | `countries` | string | No | Comma-separated list of ISO 3166-1 alpha-2 country codes \(e.g., "US,SE"\) | | `exchanges` | string | No | Comma-separated list of exchange symbols, without whitespace \(e.g., "NasdaqGS"\) | -| `states` | string | No | Comma-separated list of live states to filter by: notLive, willBeLive, live, liveFailedInterrupted, liveFailedNoAccess | +| `states` | string | No | Comma-separated list of live states to filter by: notLive, willBeLive, live, liveFailedInterrupted, liveFailedNoAccess, liveFailedNotStarted, processingRecording, processingRecordingFailed, recordingAvailable | | `startDate` | string | No | Only return events on or after this ISO 8601 date \(e.g., "2024-01-01"\) | | `endDate` | string | No | Only return events on or before this ISO 8601 date \(e.g., "2024-12-31"\) | | `transcriptVersion` | string | No | Version of the live transcript stream: "1.6" or "1.7" \(default: 1.6\) | | `updatedAfter` | string | No | Only return data updated after this ISO 8601 date \(e.g., "2024-01-01"\) | | `updatedBefore` | string | No | Only return data updated before this ISO 8601 date \(e.g., "2024-12-31"\) | -| `limit` | number | No | Maximum number of items to return in a single request \(default: 10\) | +| `limit` | number | No | Maximum number of items to return in a single request \(default: 10, max: 500\) | | `cursor` | number | No | Pagination cursor from the previous response \(nextCursor\) for the next page | | `direction` | string | No | Sort direction by id: "asc" or "desc" \(default: asc\) | @@ -677,7 +677,7 @@ List live and upcoming events from Quartr with live audio and transcript stream | ↳ `companyId` | number | Quartr company ID | | ↳ `date` | string | Scheduled event date \(ISO 8601\) | | ↳ `wentLiveAt` | string | Timestamp when the event went live \(ISO 8601\) | -| ↳ `state` | string | Live state \(notLive, willBeLive, live, liveFailedInterrupted, liveFailedNoAccess, recordingAvailable\) | +| ↳ `state` | string | Live state \(notLive, willBeLive, live, liveFailedInterrupted, liveFailedNoAccess, liveFailedNotStarted, processingRecording, processingRecordingFailed, recordingAvailable\) | | ↳ `audio` | string | URL of the live audio stream or recording | | ↳ `transcript` | string | URL of the live transcript stream \(JSON Lines\) | | ↳ `createdAt` | string | Creation timestamp \(ISO 8601\) | diff --git a/apps/sim/blocks/blocks/quartr.ts b/apps/sim/blocks/blocks/quartr.ts index 6ee6f698b6..5f4c9e3da3 100644 --- a/apps/sim/blocks/blocks/quartr.ts +++ b/apps/sim/blocks/blocks/quartr.ts @@ -43,6 +43,8 @@ const DATE_RANGE_LIST_OPERATIONS = [ 'list_live_events', ] +const UPDATED_RANGE_LIST_OPERATIONS = ['list_companies', ...DATE_RANGE_LIST_OPERATIONS] + export const QuartrBlock: BlockConfig = { type: 'quartr', name: 'Quartr', @@ -302,7 +304,7 @@ export const QuartrBlock: BlockConfig = { title: 'Updated After', type: 'short-input', placeholder: 'ISO 8601 date (e.g., 2024-01-01)', - condition: { field: 'operation', value: ALL_LIST_OPERATIONS }, + condition: { field: 'operation', value: UPDATED_RANGE_LIST_OPERATIONS }, mode: 'advanced', wandConfig: { enabled: true, @@ -316,7 +318,7 @@ export const QuartrBlock: BlockConfig = { title: 'Updated Before', type: 'short-input', placeholder: 'ISO 8601 date (e.g., 2024-12-31)', - condition: { field: 'operation', value: ALL_LIST_OPERATIONS }, + condition: { field: 'operation', value: UPDATED_RANGE_LIST_OPERATIONS }, mode: 'advanced', wandConfig: { enabled: true, @@ -443,7 +445,8 @@ export const QuartrBlock: BlockConfig = { }, summary: { type: 'string', - description: 'AI-generated event summary in Markdown', + description: + 'AI-generated event summary in Markdown (includes embedded document source tags unless a plain-text summary is requested)', condition: { field: 'operation', value: 'get_event_summary' }, }, sources: { diff --git a/apps/sim/tools/error-extractors.ts b/apps/sim/tools/error-extractors.ts index 7069b50189..ff4c442e64 100644 --- a/apps/sim/tools/error-extractors.ts +++ b/apps/sim/tools/error-extractors.ts @@ -145,6 +145,31 @@ const ERROR_EXTRACTORS: ErrorExtractorConfig[] = [ return undefined }, }, + { + id: 'nestjs-validation-errors', + description: 'NestJS validation errors with a message array of field/message objects', + examples: ['Quartr API'], + extract: (errorInfo) => { + const message = errorInfo?.data?.message + if (!Array.isArray(message) || message.length === 0) return undefined + + const entries = message + .map((entry) => { + if (typeof entry === 'string') return entry + if (entry && typeof entry === 'object' && typeof entry.message === 'string') { + return typeof entry.field === 'string' && entry.field + ? `${entry.field}: ${entry.message}` + : entry.message + } + return undefined + }) + .filter((entry): entry is string => Boolean(entry)) + if (entries.length === 0) return undefined + + const prefix = typeof errorInfo?.data?.error === 'string' ? `${errorInfo.data.error}: ` : '' + return `${prefix}${entries.join('; ')}` + }, + }, { id: 'hunter-errors', description: 'Hunter API error details', @@ -275,6 +300,7 @@ export const ErrorExtractorId = { DETAILS_ARRAY: 'details-array', DETAILS_STRING_ARRAY: 'details-string-array', BATCH_VALIDATION_ERRORS: 'batch-validation-errors', + NESTJS_VALIDATION_ERRORS: 'nestjs-validation-errors', HUNTER_ERRORS: 'hunter-errors', ERRORS_ARRAY_STRING: 'errors-array-string', TELEGRAM_DESCRIPTION: 'telegram-description', diff --git a/apps/sim/tools/quartr/get_event_summary.ts b/apps/sim/tools/quartr/get_event_summary.ts index 37833deaa0..4a0091957e 100644 --- a/apps/sim/tools/quartr/get_event_summary.ts +++ b/apps/sim/tools/quartr/get_event_summary.ts @@ -5,7 +5,12 @@ import { type QuartrSingleDto, type QuartrSummaryDto, } from '@/tools/quartr/types' -import { buildQuartrUrl, mapQuartrSummarySource, parseQuartrResponse } from '@/tools/quartr/utils' +import { + buildQuartrUrl, + isQuartrToggleEnabled, + mapQuartrSummarySource, + parseQuartrResponse, +} from '@/tools/quartr/utils' import type { ToolConfig } from '@/tools/types' export const quartrGetEventSummaryTool: ToolConfig< @@ -49,7 +54,7 @@ export const quartrGetEventSummaryTool: ToolConfig< url: (params) => buildQuartrUrl(`/events/${encodeURIComponent(String(params.eventId).trim())}/summary`, { length: params.summaryLength, - plain: params.plainSummary === true ? true : undefined, + plain: isQuartrToggleEnabled(params.plainSummary) ? true : undefined, }), method: 'GET', headers: (params) => ({ 'x-api-key': params.apiKey }), @@ -77,7 +82,8 @@ export const quartrGetEventSummaryTool: ToolConfig< outputs: { summary: { type: 'string', - description: 'AI-generated event summary in Markdown', + description: + 'AI-generated event summary in Markdown (includes embedded document source tags unless a plain-text summary is requested)', }, sources: { type: 'array', diff --git a/apps/sim/tools/quartr/list_audio.ts b/apps/sim/tools/quartr/list_audio.ts index 54b2178109..c4479ce069 100644 --- a/apps/sim/tools/quartr/list_audio.ts +++ b/apps/sim/tools/quartr/list_audio.ts @@ -8,8 +8,9 @@ import { import { buildQuartrListQuery, buildQuartrUrl, + isQuartrToggleEnabled, mapQuartrAudio, - normalizeQuartrIdList, + normalizeQuartrCommaList, parseQuartrResponse, } from '@/tools/quartr/utils' import type { ToolConfig } from '@/tools/types' @@ -105,7 +106,7 @@ export const quartrListAudioTool: ToolConfig buildQuartrUrl('/audio', { ...buildQuartrListQuery(params), - companyIds: normalizeQuartrIdList(params.companyIds), - eventIds: normalizeQuartrIdList(params.eventIds), + companyIds: normalizeQuartrCommaList(params.companyIds), + eventIds: normalizeQuartrCommaList(params.eventIds), startDate: params.startDate, endDate: params.endDate, - expand: params.expandEvent === true ? 'event' : undefined, + expand: isQuartrToggleEnabled(params.expandEvent) ? 'event' : undefined, }), method: 'GET', headers: (params) => ({ 'x-api-key': params.apiKey }), diff --git a/apps/sim/tools/quartr/list_companies.ts b/apps/sim/tools/quartr/list_companies.ts index 9019692cd8..d7ed6a3c6a 100644 --- a/apps/sim/tools/quartr/list_companies.ts +++ b/apps/sim/tools/quartr/list_companies.ts @@ -9,7 +9,7 @@ import { buildQuartrListQuery, buildQuartrUrl, mapQuartrCompany, - normalizeQuartrIdList, + normalizeQuartrCommaList, parseQuartrResponse, } from '@/tools/quartr/utils' import type { ToolConfig } from '@/tools/types' @@ -91,7 +91,7 @@ export const quartrListCompaniesTool: ToolConfig< type: 'number', required: false, visibility: 'user-or-llm', - description: 'Maximum number of items to return in a single request (default: 10)', + description: 'Maximum number of items to return in a single request (default: 10, max: 500)', }, cursor: { type: 'number', @@ -111,8 +111,8 @@ export const quartrListCompaniesTool: ToolConfig< url: (params) => buildQuartrUrl('/companies', { ...buildQuartrListQuery(params), - ids: normalizeQuartrIdList(params.companyIds), - openfigis: normalizeQuartrIdList(params.openfigis), + ids: normalizeQuartrCommaList(params.companyIds), + openfigis: normalizeQuartrCommaList(params.openfigis), }), method: 'GET', headers: (params) => ({ 'x-api-key': params.apiKey }), diff --git a/apps/sim/tools/quartr/list_document_types.ts b/apps/sim/tools/quartr/list_document_types.ts index e2dfda6ef5..6e00a5d50d 100644 --- a/apps/sim/tools/quartr/list_document_types.ts +++ b/apps/sim/tools/quartr/list_document_types.ts @@ -29,7 +29,7 @@ export const quartrListDocumentTypesTool: ToolConfig< type: 'number', required: false, visibility: 'user-or-llm', - description: 'Maximum number of items to return in a single request (default: 10)', + description: 'Maximum number of items to return in a single request (default: 10, max: 500)', }, cursor: { type: 'number', diff --git a/apps/sim/tools/quartr/list_documents.ts b/apps/sim/tools/quartr/list_documents.ts index 69d237fee1..ed71540ff2 100644 --- a/apps/sim/tools/quartr/list_documents.ts +++ b/apps/sim/tools/quartr/list_documents.ts @@ -122,7 +122,7 @@ export const quartrListDocumentsTool: ToolConfig< type: 'number', required: false, visibility: 'user-or-llm', - description: 'Maximum number of items to return in a single request (default: 10)', + description: 'Maximum number of items to return in a single request (default: 10, max: 500)', }, cursor: { type: 'number', diff --git a/apps/sim/tools/quartr/list_event_types.ts b/apps/sim/tools/quartr/list_event_types.ts index dbc425182b..a708d487c4 100644 --- a/apps/sim/tools/quartr/list_event_types.ts +++ b/apps/sim/tools/quartr/list_event_types.ts @@ -29,7 +29,7 @@ export const quartrListEventTypesTool: ToolConfig< type: 'number', required: false, visibility: 'user-or-llm', - description: 'Maximum number of items to return in a single request (default: 10)', + description: 'Maximum number of items to return in a single request (default: 10, max: 500)', }, cursor: { type: 'number', diff --git a/apps/sim/tools/quartr/list_events.ts b/apps/sim/tools/quartr/list_events.ts index 33735060d2..c34d1c58be 100644 --- a/apps/sim/tools/quartr/list_events.ts +++ b/apps/sim/tools/quartr/list_events.ts @@ -9,7 +9,7 @@ import { buildQuartrListQuery, buildQuartrUrl, mapQuartrEvent, - normalizeQuartrIdList, + normalizeQuartrCommaList, parseQuartrResponse, } from '@/tools/quartr/utils' import type { ToolConfig } from '@/tools/types' @@ -105,7 +105,7 @@ export const quartrListEventsTool: ToolConfig buildQuartrUrl('/events', { ...buildQuartrListQuery(params), - companyIds: normalizeQuartrIdList(params.companyIds), - typeIds: normalizeQuartrIdList(params.eventTypeIds), + companyIds: normalizeQuartrCommaList(params.companyIds), + typeIds: normalizeQuartrCommaList(params.eventTypeIds), startDate: params.startDate, endDate: params.endDate, sortBy: params.sortBy, diff --git a/apps/sim/tools/quartr/list_live_events.ts b/apps/sim/tools/quartr/list_live_events.ts index b688dcb678..2c4e424bbc 100644 --- a/apps/sim/tools/quartr/list_live_events.ts +++ b/apps/sim/tools/quartr/list_live_events.ts @@ -9,7 +9,7 @@ import { buildQuartrListQuery, buildQuartrUrl, mapQuartrLiveEvent, - normalizeQuartrIdList, + normalizeQuartrCommaList, parseQuartrResponse, } from '@/tools/quartr/utils' import type { ToolConfig } from '@/tools/types' @@ -79,7 +79,7 @@ export const quartrListLiveEventsTool: ToolConfig< required: false, visibility: 'user-or-llm', description: - 'Comma-separated list of live states to filter by: notLive, willBeLive, live, liveFailedInterrupted, liveFailedNoAccess', + 'Comma-separated list of live states to filter by: notLive, willBeLive, live, liveFailedInterrupted, liveFailedNoAccess, liveFailedNotStarted, processingRecording, processingRecordingFailed, recordingAvailable', }, startDate: { type: 'string', @@ -115,7 +115,7 @@ export const quartrListLiveEventsTool: ToolConfig< type: 'number', required: false, visibility: 'user-or-llm', - description: 'Maximum number of items to return in a single request (default: 10)', + description: 'Maximum number of items to return in a single request (default: 10, max: 500)', }, cursor: { type: 'number', @@ -135,9 +135,9 @@ export const quartrListLiveEventsTool: ToolConfig< url: (params) => buildQuartrUrl('/live', { ...buildQuartrListQuery(params), - companyIds: normalizeQuartrIdList(params.companyIds), - eventIds: normalizeQuartrIdList(params.eventIds), - states: normalizeQuartrIdList(params.states), + companyIds: normalizeQuartrCommaList(params.companyIds), + eventIds: normalizeQuartrCommaList(params.eventIds), + states: normalizeQuartrCommaList(params.states), startDate: params.startDate, endDate: params.endDate, transcriptVersion: params.transcriptVersion, diff --git a/apps/sim/tools/quartr/list_reports.ts b/apps/sim/tools/quartr/list_reports.ts index 5d105db508..afd2fb31bd 100644 --- a/apps/sim/tools/quartr/list_reports.ts +++ b/apps/sim/tools/quartr/list_reports.ts @@ -122,7 +122,7 @@ export const quartrListReportsTool: ToolConfig< type: 'number', required: false, visibility: 'user-or-llm', - description: 'Maximum number of items to return in a single request (default: 10)', + description: 'Maximum number of items to return in a single request (default: 10, max: 500)', }, cursor: { type: 'number', diff --git a/apps/sim/tools/quartr/list_slide_decks.ts b/apps/sim/tools/quartr/list_slide_decks.ts index c4628132ed..6bd3be42bf 100644 --- a/apps/sim/tools/quartr/list_slide_decks.ts +++ b/apps/sim/tools/quartr/list_slide_decks.ts @@ -122,7 +122,7 @@ export const quartrListSlideDecksTool: ToolConfig< type: 'number', required: false, visibility: 'user-or-llm', - description: 'Maximum number of items to return in a single request (default: 10)', + description: 'Maximum number of items to return in a single request (default: 10, max: 500)', }, cursor: { type: 'number', diff --git a/apps/sim/tools/quartr/list_transcripts.ts b/apps/sim/tools/quartr/list_transcripts.ts index 280cbadace..ea525ca334 100644 --- a/apps/sim/tools/quartr/list_transcripts.ts +++ b/apps/sim/tools/quartr/list_transcripts.ts @@ -122,7 +122,7 @@ export const quartrListTranscriptsTool: ToolConfig< type: 'number', required: false, visibility: 'user-or-llm', - description: 'Maximum number of items to return in a single request (default: 10)', + description: 'Maximum number of items to return in a single request (default: 10, max: 500)', }, cursor: { type: 'number', diff --git a/apps/sim/tools/quartr/types.ts b/apps/sim/tools/quartr/types.ts index fddddde7fa..2641f30077 100644 --- a/apps/sim/tools/quartr/types.ts +++ b/apps/sim/tools/quartr/types.ts @@ -324,7 +324,7 @@ export interface QuartrGetEventSummaryParams { apiKey: string eventId: number | string summaryLength?: string - plainSummary?: boolean + plainSummary?: boolean | string } export interface QuartrListEventTypesParams extends QuartrPaginationParams { @@ -347,7 +347,7 @@ export interface QuartrListDocumentsParams documentGroupIds?: string startDate?: string endDate?: string - expandEvent?: boolean + expandEvent?: boolean | string } export interface QuartrGetReportParams { @@ -374,7 +374,7 @@ export interface QuartrListAudioParams eventIds?: string startDate?: string endDate?: string - expandEvent?: boolean + expandEvent?: boolean | string } export interface QuartrGetAudioParams { @@ -634,7 +634,7 @@ export const QUARTR_LIVE_EVENT_OUTPUT_PROPERTIES = { state: { type: 'string', description: - 'Live state (notLive, willBeLive, live, liveFailedInterrupted, liveFailedNoAccess, recordingAvailable)', + 'Live state (notLive, willBeLive, live, liveFailedInterrupted, liveFailedNoAccess, liveFailedNotStarted, processingRecording, processingRecordingFailed, recordingAvailable)', nullable: true, }, audio: { diff --git a/apps/sim/tools/quartr/utils.ts b/apps/sim/tools/quartr/utils.ts index 2d2519b67d..a43585fa33 100644 --- a/apps/sim/tools/quartr/utils.ts +++ b/apps/sim/tools/quartr/utils.ts @@ -29,9 +29,11 @@ export const QUARTR_API_BASE_URL = 'https://api.quartr.com/public/v3' * Normalizes a comma-separated list value by trimming whitespace around each * entry, since the Quartr API expects lists without blank spaces. */ -function normalizeCommaList(value: string | undefined): string | undefined { - if (!value) return undefined - const normalized = value +export function normalizeQuartrCommaList( + value: string | number | null | undefined +): string | undefined { + if (value == null || value === '') return undefined + const normalized = String(value) .split(',') .map((entry) => entry.trim()) .filter(Boolean) @@ -39,17 +41,25 @@ function normalizeCommaList(value: string | undefined): string | undefined { return normalized || undefined } +/** + * Interprets a boolean-ish tool param, accepting boolean true or the string + * "true" (agent tool configuration serializes switch values as strings). + */ +export function isQuartrToggleEnabled(value: boolean | string | null | undefined): boolean { + return value === true || value === 'true' +} + /** * Builds a Quartr API URL, appending only query parameters that have a value. */ export function buildQuartrUrl( path: string, - query?: Record + query?: Record ): string { const url = new URL(`${QUARTR_API_BASE_URL}${path}`) if (query) { for (const [key, value] of Object.entries(query)) { - if (value === undefined || value === '') continue + if (value == null || value === '') continue url.searchParams.set(key, String(value)) } } @@ -64,11 +74,11 @@ export function buildQuartrListQuery( params: QuartrCompanyFilterParams & QuartrPaginationParams & QuartrUpdatedRangeParams ): Record { return { - tickers: normalizeCommaList(params.tickers), - isins: normalizeCommaList(params.isins), - ciks: normalizeCommaList(params.ciks), - countries: normalizeCommaList(params.countries), - exchanges: normalizeCommaList(params.exchanges), + tickers: normalizeQuartrCommaList(params.tickers), + isins: normalizeQuartrCommaList(params.isins), + ciks: normalizeQuartrCommaList(params.ciks), + countries: normalizeQuartrCommaList(params.countries), + exchanges: normalizeQuartrCommaList(params.exchanges), limit: params.limit, cursor: params.cursor, direction: params.direction, @@ -77,13 +87,6 @@ export function buildQuartrListQuery( } } -/** - * Normalizes a comma-separated identifier list for query usage. - */ -export function normalizeQuartrIdList(value: string | undefined): string | undefined { - return normalizeCommaList(value) -} - /** * Builds the query parameters shared by the documents, reports, slide decks, * and transcripts list tools. @@ -93,13 +96,13 @@ export function buildQuartrDocumentListQuery( ): Record { return { ...buildQuartrListQuery(params), - companyIds: normalizeCommaList(params.companyIds), - eventIds: normalizeCommaList(params.eventIds), - typeIds: normalizeCommaList(params.documentTypeIds), - documentGroupIds: normalizeCommaList(params.documentGroupIds), + companyIds: normalizeQuartrCommaList(params.companyIds), + eventIds: normalizeQuartrCommaList(params.eventIds), + typeIds: normalizeQuartrCommaList(params.documentTypeIds), + documentGroupIds: normalizeQuartrCommaList(params.documentGroupIds), startDate: params.startDate, endDate: params.endDate, - expand: params.expandEvent === true ? 'event' : undefined, + expand: isQuartrToggleEnabled(params.expandEvent) ? 'event' : undefined, } } @@ -116,9 +119,21 @@ export async function parseQuartrResponse(response: Response, operation: stri } if (!response.ok) { - const body = data as { message?: string | string[]; error?: string } | undefined + const body = data as + | { message?: string | Array; error?: string } + | undefined const rawMessage = body?.message ?? body?.error ?? `HTTP ${response.status}` - const message = Array.isArray(rawMessage) ? rawMessage.join(', ') : rawMessage + const message = Array.isArray(rawMessage) + ? rawMessage + .map((entry) => { + if (typeof entry === 'string') return entry + if (typeof entry?.message === 'string') { + return entry.field ? `${entry.field}: ${entry.message}` : entry.message + } + return JSON.stringify(entry) + }) + .join('; ') + : rawMessage throw new Error(`Quartr ${operation} failed (${response.status}): ${message}`) }