@outlit/cli 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +795 -178
- package/package.json +4 -3
package/dist/cli.js
CHANGED
|
@@ -104,7 +104,7 @@ var package_default;
|
|
|
104
104
|
var init_package = __esm(() => {
|
|
105
105
|
package_default = {
|
|
106
106
|
name: "@outlit/cli",
|
|
107
|
-
version: "1.
|
|
107
|
+
version: "1.6.0",
|
|
108
108
|
description: "CLI for Outlit customer intelligence platform",
|
|
109
109
|
license: "Apache-2.0",
|
|
110
110
|
repository: {
|
|
@@ -134,8 +134,9 @@ var init_package = __esm(() => {
|
|
|
134
134
|
typecheck: "tsc --noEmit"
|
|
135
135
|
},
|
|
136
136
|
dependencies: {
|
|
137
|
-
|
|
138
|
-
"@
|
|
137
|
+
"@clack/prompts": "^1.0.1",
|
|
138
|
+
"@outlit/tools": "^0.1.0",
|
|
139
|
+
citty: "^0.2.1"
|
|
139
140
|
},
|
|
140
141
|
devDependencies: {
|
|
141
142
|
typescript: "^5.9.3",
|
|
@@ -1488,6 +1489,725 @@ var init_signup = __esm(() => {
|
|
|
1488
1489
|
});
|
|
1489
1490
|
});
|
|
1490
1491
|
|
|
1492
|
+
// ../tools/dist/index.js
|
|
1493
|
+
function isCustomerToolName(value) {
|
|
1494
|
+
return customerToolNameSet.has(value);
|
|
1495
|
+
}
|
|
1496
|
+
function resolveCustomerContextSearchInput(value) {
|
|
1497
|
+
if (!value.query) {
|
|
1498
|
+
return {
|
|
1499
|
+
ok: false,
|
|
1500
|
+
message: "A query argument is required"
|
|
1501
|
+
};
|
|
1502
|
+
}
|
|
1503
|
+
const normalizedQuery = value.query.trim();
|
|
1504
|
+
if (normalizedQuery.length < 2) {
|
|
1505
|
+
return {
|
|
1506
|
+
ok: false,
|
|
1507
|
+
message: "Query must be at least 2 non-whitespace characters"
|
|
1508
|
+
};
|
|
1509
|
+
}
|
|
1510
|
+
if (value.after !== undefined && !iso8601UtcDateTimeRegex.test(value.after)) {
|
|
1511
|
+
return {
|
|
1512
|
+
ok: false,
|
|
1513
|
+
message: "--after must be a valid ISO 8601 datetime"
|
|
1514
|
+
};
|
|
1515
|
+
}
|
|
1516
|
+
const afterTime = value.after === undefined ? undefined : new Date(value.after).getTime();
|
|
1517
|
+
if (afterTime !== undefined && Number.isNaN(afterTime)) {
|
|
1518
|
+
return {
|
|
1519
|
+
ok: false,
|
|
1520
|
+
message: "--after must be a valid ISO 8601 datetime"
|
|
1521
|
+
};
|
|
1522
|
+
}
|
|
1523
|
+
if (value.before !== undefined && !iso8601UtcDateTimeRegex.test(value.before)) {
|
|
1524
|
+
return {
|
|
1525
|
+
ok: false,
|
|
1526
|
+
message: "--before must be a valid ISO 8601 datetime"
|
|
1527
|
+
};
|
|
1528
|
+
}
|
|
1529
|
+
const beforeTime = value.before === undefined ? undefined : new Date(value.before).getTime();
|
|
1530
|
+
if (beforeTime !== undefined && Number.isNaN(beforeTime)) {
|
|
1531
|
+
return {
|
|
1532
|
+
ok: false,
|
|
1533
|
+
message: "--before must be a valid ISO 8601 datetime"
|
|
1534
|
+
};
|
|
1535
|
+
}
|
|
1536
|
+
if (afterTime !== undefined && beforeTime !== undefined && afterTime > beforeTime) {
|
|
1537
|
+
return {
|
|
1538
|
+
ok: false,
|
|
1539
|
+
message: "--after must be before or equal to --before"
|
|
1540
|
+
};
|
|
1541
|
+
}
|
|
1542
|
+
return {
|
|
1543
|
+
ok: true,
|
|
1544
|
+
request: {
|
|
1545
|
+
query: normalizedQuery,
|
|
1546
|
+
customer: value.customer,
|
|
1547
|
+
topK: value.topK,
|
|
1548
|
+
after: value.after,
|
|
1549
|
+
before: value.before,
|
|
1550
|
+
sourceTypes: value.sourceTypes
|
|
1551
|
+
}
|
|
1552
|
+
};
|
|
1553
|
+
}
|
|
1554
|
+
function createOutlitClient(options) {
|
|
1555
|
+
const key = options.apiKey.trim();
|
|
1556
|
+
const baseUrl = options.baseUrl ?? DEFAULT_OUTLIT_API_URL;
|
|
1557
|
+
const fetchImpl = options.fetch ?? globalThis.fetch;
|
|
1558
|
+
if (!key) {
|
|
1559
|
+
throw new Error("apiKey is required");
|
|
1560
|
+
}
|
|
1561
|
+
if (!fetchImpl) {
|
|
1562
|
+
throw new Error("fetch is not available");
|
|
1563
|
+
}
|
|
1564
|
+
return {
|
|
1565
|
+
key,
|
|
1566
|
+
baseUrl,
|
|
1567
|
+
async callTool(toolName, input = {}) {
|
|
1568
|
+
if (!isCustomerToolName(toolName)) {
|
|
1569
|
+
throw new Error(`Unknown customer tool: ${toolName}`);
|
|
1570
|
+
}
|
|
1571
|
+
const response = await fetchImpl(new URL("/api/tools/call", baseUrl).toString(), {
|
|
1572
|
+
method: "POST",
|
|
1573
|
+
headers: {
|
|
1574
|
+
Authorization: `Bearer ${key}`,
|
|
1575
|
+
"Content-Type": "application/json"
|
|
1576
|
+
},
|
|
1577
|
+
body: JSON.stringify({
|
|
1578
|
+
tool: toolName,
|
|
1579
|
+
input
|
|
1580
|
+
})
|
|
1581
|
+
});
|
|
1582
|
+
if (!response.ok) {
|
|
1583
|
+
const text = await response.text();
|
|
1584
|
+
throw new Error(`API error (${response.status}): ${text}`);
|
|
1585
|
+
}
|
|
1586
|
+
return response.json();
|
|
1587
|
+
}
|
|
1588
|
+
};
|
|
1589
|
+
}
|
|
1590
|
+
var customerToolNames, customerToolContracts, customerBillingStatuses, customerFactStatuses, customerFactTypes, unsupportedCustomerFactTypes, customerFactCategories, customerIncludeSections, customerSourceTypes, customerTimeframes, timelineChannels, timelineTimeframes, userJourneyStages, schemaTables, customerToolNameSet, iso8601UtcDateTimeRegex, DEFAULT_OUTLIT_API_URL = "https://app.outlit.ai", defaultAgentToolNames, sqlToolNames, analyticalAgentToolNames;
|
|
1591
|
+
var init_dist4 = __esm(() => {
|
|
1592
|
+
customerToolNames = [
|
|
1593
|
+
"outlit_list_customers",
|
|
1594
|
+
"outlit_list_users",
|
|
1595
|
+
"outlit_get_customer",
|
|
1596
|
+
"outlit_get_timeline",
|
|
1597
|
+
"outlit_list_facts",
|
|
1598
|
+
"outlit_get_fact",
|
|
1599
|
+
"outlit_get_source",
|
|
1600
|
+
"outlit_search_customer_context",
|
|
1601
|
+
"outlit_query",
|
|
1602
|
+
"outlit_schema"
|
|
1603
|
+
];
|
|
1604
|
+
customerToolContracts = {
|
|
1605
|
+
outlit_list_customers: {
|
|
1606
|
+
toolName: "outlit_list_customers",
|
|
1607
|
+
description: "Browse and filter customers. Use this to find customers by billing status, activity recency, revenue, or name. Returns a paginated list with summary info (MRR, last activity, status).",
|
|
1608
|
+
inputSchema: {
|
|
1609
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
1610
|
+
type: "object",
|
|
1611
|
+
properties: {
|
|
1612
|
+
billingStatus: {
|
|
1613
|
+
description: "Filter by billing status",
|
|
1614
|
+
type: "string",
|
|
1615
|
+
enum: ["NONE", "TRIALING", "PAYING", "PAST_DUE", "CHURNED"]
|
|
1616
|
+
},
|
|
1617
|
+
hasActivityInLast: {
|
|
1618
|
+
description: "Filter customers with activity in the last N days",
|
|
1619
|
+
type: "string",
|
|
1620
|
+
enum: ["7d", "14d", "30d", "90d"]
|
|
1621
|
+
},
|
|
1622
|
+
noActivityInLast: {
|
|
1623
|
+
description: "Filter customers with NO activity in the last N days",
|
|
1624
|
+
type: "string",
|
|
1625
|
+
enum: ["7d", "14d", "30d", "90d"]
|
|
1626
|
+
},
|
|
1627
|
+
mrrAbove: {
|
|
1628
|
+
description: "Minimum MRR in cents (e.g., 10000 = $100)",
|
|
1629
|
+
type: "number",
|
|
1630
|
+
minimum: 0
|
|
1631
|
+
},
|
|
1632
|
+
mrrBelow: {
|
|
1633
|
+
description: "Maximum MRR in cents",
|
|
1634
|
+
type: "number",
|
|
1635
|
+
minimum: 0
|
|
1636
|
+
},
|
|
1637
|
+
traitFilters: {
|
|
1638
|
+
description: "Filter by exact trait values using key/value pairs",
|
|
1639
|
+
type: "object",
|
|
1640
|
+
propertyNames: {
|
|
1641
|
+
type: "string",
|
|
1642
|
+
pattern: "^[A-Za-z0-9_-]{1,100}$"
|
|
1643
|
+
},
|
|
1644
|
+
additionalProperties: {
|
|
1645
|
+
anyOf: [
|
|
1646
|
+
{
|
|
1647
|
+
type: "string",
|
|
1648
|
+
maxLength: 500
|
|
1649
|
+
},
|
|
1650
|
+
{
|
|
1651
|
+
type: "number"
|
|
1652
|
+
},
|
|
1653
|
+
{
|
|
1654
|
+
type: "boolean"
|
|
1655
|
+
}
|
|
1656
|
+
]
|
|
1657
|
+
}
|
|
1658
|
+
},
|
|
1659
|
+
search: {
|
|
1660
|
+
description: "Search by customer name or domain (case-insensitive)",
|
|
1661
|
+
type: "string",
|
|
1662
|
+
maxLength: 500
|
|
1663
|
+
},
|
|
1664
|
+
limit: {
|
|
1665
|
+
description: "Results per page (max 1000)",
|
|
1666
|
+
default: 50,
|
|
1667
|
+
type: "number",
|
|
1668
|
+
minimum: 1,
|
|
1669
|
+
maximum: 1000
|
|
1670
|
+
},
|
|
1671
|
+
cursor: {
|
|
1672
|
+
description: "Pagination cursor from previous response",
|
|
1673
|
+
type: "string"
|
|
1674
|
+
},
|
|
1675
|
+
orderBy: {
|
|
1676
|
+
description: "Field to order results by",
|
|
1677
|
+
default: "last_activity_at",
|
|
1678
|
+
type: "string",
|
|
1679
|
+
enum: ["last_activity_at", "first_seen_at", "name", "mrr_cents"]
|
|
1680
|
+
},
|
|
1681
|
+
orderDirection: {
|
|
1682
|
+
description: "Sort direction",
|
|
1683
|
+
default: "desc",
|
|
1684
|
+
type: "string",
|
|
1685
|
+
enum: ["asc", "desc"]
|
|
1686
|
+
}
|
|
1687
|
+
},
|
|
1688
|
+
additionalProperties: false
|
|
1689
|
+
}
|
|
1690
|
+
},
|
|
1691
|
+
outlit_list_users: {
|
|
1692
|
+
toolName: "outlit_list_users",
|
|
1693
|
+
description: "Browse and filter users. Use this to find users by journey stage, activity recency, customer, or email/name. Returns a paginated list with activity info.",
|
|
1694
|
+
inputSchema: {
|
|
1695
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
1696
|
+
type: "object",
|
|
1697
|
+
properties: {
|
|
1698
|
+
journeyStage: {
|
|
1699
|
+
description: "Filter by user journey stage",
|
|
1700
|
+
type: "string",
|
|
1701
|
+
enum: ["DISCOVERED", "SIGNED_UP", "ACTIVATED", "ENGAGED", "INACTIVE"]
|
|
1702
|
+
},
|
|
1703
|
+
customerId: {
|
|
1704
|
+
description: "Filter users by customer ID",
|
|
1705
|
+
type: "string",
|
|
1706
|
+
maxLength: 500
|
|
1707
|
+
},
|
|
1708
|
+
traitFilters: {
|
|
1709
|
+
description: "Filter by exact trait values using key/value pairs",
|
|
1710
|
+
type: "object",
|
|
1711
|
+
propertyNames: {
|
|
1712
|
+
type: "string",
|
|
1713
|
+
pattern: "^[A-Za-z0-9_-]{1,100}$"
|
|
1714
|
+
},
|
|
1715
|
+
additionalProperties: {
|
|
1716
|
+
anyOf: [
|
|
1717
|
+
{
|
|
1718
|
+
type: "string",
|
|
1719
|
+
maxLength: 500
|
|
1720
|
+
},
|
|
1721
|
+
{
|
|
1722
|
+
type: "number"
|
|
1723
|
+
},
|
|
1724
|
+
{
|
|
1725
|
+
type: "boolean"
|
|
1726
|
+
}
|
|
1727
|
+
]
|
|
1728
|
+
}
|
|
1729
|
+
},
|
|
1730
|
+
hasActivityInLast: {
|
|
1731
|
+
description: "Filter users active within this window. Format: Nd, Nh, or Nm (e.g., '7d', '24h', '90m')",
|
|
1732
|
+
type: "string",
|
|
1733
|
+
pattern: "^\\d+(d|h|m)$"
|
|
1734
|
+
},
|
|
1735
|
+
noActivityInLast: {
|
|
1736
|
+
description: "Filter users NOT active within this window. Format: Nd, Nh, or Nm (e.g., '30d', '2h')",
|
|
1737
|
+
type: "string",
|
|
1738
|
+
pattern: "^\\d+(d|h|m)$"
|
|
1739
|
+
},
|
|
1740
|
+
search: {
|
|
1741
|
+
description: "Search by user email or name (case-insensitive)",
|
|
1742
|
+
type: "string",
|
|
1743
|
+
maxLength: 500
|
|
1744
|
+
},
|
|
1745
|
+
limit: {
|
|
1746
|
+
description: "Results per page (max 1000)",
|
|
1747
|
+
default: 50,
|
|
1748
|
+
type: "number",
|
|
1749
|
+
minimum: 1,
|
|
1750
|
+
maximum: 1000
|
|
1751
|
+
},
|
|
1752
|
+
cursor: {
|
|
1753
|
+
description: "Pagination cursor from previous response",
|
|
1754
|
+
type: "string"
|
|
1755
|
+
},
|
|
1756
|
+
orderBy: {
|
|
1757
|
+
description: "Field to order by",
|
|
1758
|
+
default: "last_activity_at",
|
|
1759
|
+
type: "string",
|
|
1760
|
+
enum: ["last_activity_at", "first_seen_at", "email"]
|
|
1761
|
+
},
|
|
1762
|
+
orderDirection: {
|
|
1763
|
+
description: "Sort direction",
|
|
1764
|
+
default: "desc",
|
|
1765
|
+
type: "string",
|
|
1766
|
+
enum: ["asc", "desc"]
|
|
1767
|
+
}
|
|
1768
|
+
},
|
|
1769
|
+
additionalProperties: false
|
|
1770
|
+
}
|
|
1771
|
+
},
|
|
1772
|
+
outlit_get_customer: {
|
|
1773
|
+
toolName: "outlit_get_customer",
|
|
1774
|
+
description: "Get full details for a single customer. Use this when you already know which customer you want to inspect. Optionally include related data (users, revenue, recent activity, engagement metrics).",
|
|
1775
|
+
inputSchema: {
|
|
1776
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
1777
|
+
type: "object",
|
|
1778
|
+
properties: {
|
|
1779
|
+
customer: {
|
|
1780
|
+
type: "string",
|
|
1781
|
+
description: "Customer ID, domain, or name to look up"
|
|
1782
|
+
},
|
|
1783
|
+
include: {
|
|
1784
|
+
description: "Additional data sections to include in the response",
|
|
1785
|
+
type: "array",
|
|
1786
|
+
items: {
|
|
1787
|
+
type: "string",
|
|
1788
|
+
enum: ["users", "revenue", "recentTimeline", "behaviorMetrics"]
|
|
1789
|
+
}
|
|
1790
|
+
},
|
|
1791
|
+
timeframe: {
|
|
1792
|
+
description: "Timeframe for timeline and behavior metrics (default: 30d)",
|
|
1793
|
+
default: "30d",
|
|
1794
|
+
type: "string",
|
|
1795
|
+
enum: ["7d", "14d", "30d", "90d"]
|
|
1796
|
+
}
|
|
1797
|
+
},
|
|
1798
|
+
required: ["customer"],
|
|
1799
|
+
additionalProperties: false
|
|
1800
|
+
}
|
|
1801
|
+
},
|
|
1802
|
+
outlit_get_timeline: {
|
|
1803
|
+
toolName: "outlit_get_timeline",
|
|
1804
|
+
description: "Get the chronological activity timeline for a customer. Use this to see what happened and when — emails, calls, Slack messages, billing events, etc. Supports channel and date filtering.",
|
|
1805
|
+
inputSchema: {
|
|
1806
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
1807
|
+
type: "object",
|
|
1808
|
+
properties: {
|
|
1809
|
+
customer: {
|
|
1810
|
+
type: "string",
|
|
1811
|
+
description: "Customer ID or domain"
|
|
1812
|
+
},
|
|
1813
|
+
channels: {
|
|
1814
|
+
description: "Filter by event channel (e.g., EMAIL, SLACK, CALL)",
|
|
1815
|
+
type: "array",
|
|
1816
|
+
items: {
|
|
1817
|
+
type: "string",
|
|
1818
|
+
enum: ["SDK", "EMAIL", "SLACK", "CALL", "CRM", "BILLING", "SUPPORT", "INTERNAL"]
|
|
1819
|
+
}
|
|
1820
|
+
},
|
|
1821
|
+
eventTypes: {
|
|
1822
|
+
description: "Filter by event type",
|
|
1823
|
+
type: "array",
|
|
1824
|
+
items: {
|
|
1825
|
+
type: "string"
|
|
1826
|
+
}
|
|
1827
|
+
},
|
|
1828
|
+
timeframe: {
|
|
1829
|
+
description: "Relative time window (default: 30d). Cannot be used with startDate/endDate.",
|
|
1830
|
+
type: "string",
|
|
1831
|
+
enum: ["7d", "14d", "30d", "90d", "all"]
|
|
1832
|
+
},
|
|
1833
|
+
startDate: {
|
|
1834
|
+
description: "Start of time window (ISO 8601, e.g. '2025-01-01T00:00:00Z'). Cannot be used with timeframe.",
|
|
1835
|
+
type: "string",
|
|
1836
|
+
format: "date-time",
|
|
1837
|
+
pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
|
|
1838
|
+
},
|
|
1839
|
+
endDate: {
|
|
1840
|
+
description: "End of time window (ISO 8601, e.g. '2025-01-31T23:59:59Z'). Cannot be used with timeframe.",
|
|
1841
|
+
type: "string",
|
|
1842
|
+
format: "date-time",
|
|
1843
|
+
pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
|
|
1844
|
+
},
|
|
1845
|
+
limit: {
|
|
1846
|
+
description: "Results per page (max 1000)",
|
|
1847
|
+
default: 50,
|
|
1848
|
+
type: "number",
|
|
1849
|
+
minimum: 1,
|
|
1850
|
+
maximum: 1000
|
|
1851
|
+
},
|
|
1852
|
+
cursor: {
|
|
1853
|
+
description: "Pagination cursor from previous response",
|
|
1854
|
+
type: "string"
|
|
1855
|
+
}
|
|
1856
|
+
},
|
|
1857
|
+
required: ["customer"],
|
|
1858
|
+
additionalProperties: false
|
|
1859
|
+
}
|
|
1860
|
+
},
|
|
1861
|
+
outlit_list_facts: {
|
|
1862
|
+
toolName: "outlit_list_facts",
|
|
1863
|
+
description: "List structured facts known about a customer. Use filters like status, sourceTypes, factTypes, factCategories, and date bounds to narrow the result set. For topic-specific retrieval, use outlit_search_customer_context instead.",
|
|
1864
|
+
inputSchema: {
|
|
1865
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
1866
|
+
type: "object",
|
|
1867
|
+
properties: {
|
|
1868
|
+
customer: {
|
|
1869
|
+
type: "string",
|
|
1870
|
+
description: "Customer ID or domain"
|
|
1871
|
+
},
|
|
1872
|
+
status: {
|
|
1873
|
+
description: "Optional fact status filter",
|
|
1874
|
+
type: "array",
|
|
1875
|
+
items: {
|
|
1876
|
+
type: "string",
|
|
1877
|
+
enum: ["ACTIVE", "ACKNOWLEDGED", "RESOLVED", "SNOOZED", "CANDIDATE"]
|
|
1878
|
+
}
|
|
1879
|
+
},
|
|
1880
|
+
sourceTypes: {
|
|
1881
|
+
description: "Optional generic source types to restrict fact results to.",
|
|
1882
|
+
type: "array",
|
|
1883
|
+
items: {
|
|
1884
|
+
type: "string",
|
|
1885
|
+
enum: ["EMAIL", "CALL", "CALENDAR_EVENT", "SUPPORT_TICKET"]
|
|
1886
|
+
}
|
|
1887
|
+
},
|
|
1888
|
+
factTypes: {
|
|
1889
|
+
description: "Optional customer-memory fact type filters, such as CHURN_RISK, EXPANSION, SENTIMENT, or BUDGET. Anomaly detector fact types are not supported.",
|
|
1890
|
+
type: "array",
|
|
1891
|
+
items: {
|
|
1892
|
+
type: "string",
|
|
1893
|
+
enum: [
|
|
1894
|
+
"CUSTOM",
|
|
1895
|
+
"COMPANY_CHANGE",
|
|
1896
|
+
"FUNDING_REVENUE",
|
|
1897
|
+
"TECHNOLOGY",
|
|
1898
|
+
"STRATEGY",
|
|
1899
|
+
"COMPETITIVE",
|
|
1900
|
+
"SENTIMENT",
|
|
1901
|
+
"CHAMPION_RISK",
|
|
1902
|
+
"EXPANSION",
|
|
1903
|
+
"CHURN_RISK",
|
|
1904
|
+
"TIMELINE",
|
|
1905
|
+
"BUDGET",
|
|
1906
|
+
"DECISION_MAKER",
|
|
1907
|
+
"REQUIREMENTS",
|
|
1908
|
+
"PRODUCT_USAGE",
|
|
1909
|
+
"CONTACT_INFO",
|
|
1910
|
+
"CONTACT_PREFERENCE"
|
|
1911
|
+
]
|
|
1912
|
+
}
|
|
1913
|
+
},
|
|
1914
|
+
factCategories: {
|
|
1915
|
+
description: "Optional public fact category filters. Supported values: MEMORY, CUSTOM.",
|
|
1916
|
+
type: "array",
|
|
1917
|
+
items: {
|
|
1918
|
+
type: "string",
|
|
1919
|
+
enum: ["MEMORY", "CUSTOM"]
|
|
1920
|
+
}
|
|
1921
|
+
},
|
|
1922
|
+
after: {
|
|
1923
|
+
description: "ISO 8601 datetime lower bound",
|
|
1924
|
+
type: "string",
|
|
1925
|
+
format: "date-time",
|
|
1926
|
+
pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
|
|
1927
|
+
},
|
|
1928
|
+
before: {
|
|
1929
|
+
description: "ISO 8601 datetime upper bound",
|
|
1930
|
+
type: "string",
|
|
1931
|
+
format: "date-time",
|
|
1932
|
+
pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
|
|
1933
|
+
},
|
|
1934
|
+
limit: {
|
|
1935
|
+
description: "Results per page (max 100)",
|
|
1936
|
+
default: 50,
|
|
1937
|
+
type: "number",
|
|
1938
|
+
minimum: 1,
|
|
1939
|
+
maximum: 100
|
|
1940
|
+
},
|
|
1941
|
+
cursor: {
|
|
1942
|
+
description: "Pagination cursor from previous response",
|
|
1943
|
+
type: "string"
|
|
1944
|
+
}
|
|
1945
|
+
},
|
|
1946
|
+
required: ["customer"],
|
|
1947
|
+
additionalProperties: false
|
|
1948
|
+
}
|
|
1949
|
+
},
|
|
1950
|
+
outlit_get_fact: {
|
|
1951
|
+
toolName: "outlit_get_fact",
|
|
1952
|
+
description: "Get one exact fact by ID. Returns the canonical fact shape and optionally expands requested related data such as evidence.",
|
|
1953
|
+
inputSchema: {
|
|
1954
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
1955
|
+
type: "object",
|
|
1956
|
+
properties: {
|
|
1957
|
+
factId: {
|
|
1958
|
+
type: "string",
|
|
1959
|
+
minLength: 1,
|
|
1960
|
+
maxLength: 500,
|
|
1961
|
+
description: "Exact fact ID to retrieve"
|
|
1962
|
+
},
|
|
1963
|
+
include: {
|
|
1964
|
+
description: "Optional best-effort expansions. Use include=['evidence'] to request evidence when available; unsupported include values are ignored.",
|
|
1965
|
+
type: "array",
|
|
1966
|
+
items: {
|
|
1967
|
+
type: "string",
|
|
1968
|
+
minLength: 1,
|
|
1969
|
+
maxLength: 100
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
},
|
|
1973
|
+
required: ["factId"],
|
|
1974
|
+
additionalProperties: false
|
|
1975
|
+
}
|
|
1976
|
+
},
|
|
1977
|
+
outlit_get_source: {
|
|
1978
|
+
toolName: "outlit_get_source",
|
|
1979
|
+
description: "Get one exact source record by generic sourceType and sourceId. Use this when you already know the concrete underlying source you want to inspect.",
|
|
1980
|
+
inputSchema: {
|
|
1981
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
1982
|
+
type: "object",
|
|
1983
|
+
properties: {
|
|
1984
|
+
sourceType: {
|
|
1985
|
+
type: "string",
|
|
1986
|
+
enum: ["EMAIL", "CALL", "CALENDAR_EVENT", "SUPPORT_TICKET"]
|
|
1987
|
+
},
|
|
1988
|
+
sourceId: {
|
|
1989
|
+
type: "string",
|
|
1990
|
+
minLength: 1,
|
|
1991
|
+
maxLength: 500
|
|
1992
|
+
}
|
|
1993
|
+
},
|
|
1994
|
+
required: ["sourceType", "sourceId"],
|
|
1995
|
+
additionalProperties: false
|
|
1996
|
+
}
|
|
1997
|
+
},
|
|
1998
|
+
outlit_search_customer_context: {
|
|
1999
|
+
toolName: "outlit_search_customer_context",
|
|
2000
|
+
description: "Search across all known customer context using a natural-language query. Returns grouped artifact-level results for matching sources and facts. Omit customer to search across all customers in the organization.",
|
|
2001
|
+
inputSchema: {
|
|
2002
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
2003
|
+
type: "object",
|
|
2004
|
+
properties: {
|
|
2005
|
+
customer: {
|
|
2006
|
+
description: "Customer ID, domain, or name. Omit to search across all customers.",
|
|
2007
|
+
anyOf: [
|
|
2008
|
+
{
|
|
2009
|
+
type: "string",
|
|
2010
|
+
minLength: 1,
|
|
2011
|
+
maxLength: 500
|
|
2012
|
+
},
|
|
2013
|
+
{
|
|
2014
|
+
type: "null"
|
|
2015
|
+
}
|
|
2016
|
+
]
|
|
2017
|
+
},
|
|
2018
|
+
query: {
|
|
2019
|
+
type: "string",
|
|
2020
|
+
minLength: 2,
|
|
2021
|
+
maxLength: 2000,
|
|
2022
|
+
description: "Natural language query or topic to search for."
|
|
2023
|
+
},
|
|
2024
|
+
topK: {
|
|
2025
|
+
description: "Maximum number of artifact results to return (default 20).",
|
|
2026
|
+
type: "integer",
|
|
2027
|
+
minimum: 1,
|
|
2028
|
+
maximum: 50
|
|
2029
|
+
},
|
|
2030
|
+
after: {
|
|
2031
|
+
description: "ISO 8601 datetime lower bound",
|
|
2032
|
+
type: "string",
|
|
2033
|
+
format: "date-time",
|
|
2034
|
+
pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
|
|
2035
|
+
},
|
|
2036
|
+
before: {
|
|
2037
|
+
description: "ISO 8601 datetime upper bound",
|
|
2038
|
+
type: "string",
|
|
2039
|
+
format: "date-time",
|
|
2040
|
+
pattern: "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
|
|
2041
|
+
},
|
|
2042
|
+
sourceTypes: {
|
|
2043
|
+
description: "Optional generic source types to restrict the search to.",
|
|
2044
|
+
type: "array",
|
|
2045
|
+
items: {
|
|
2046
|
+
type: "string",
|
|
2047
|
+
enum: ["EMAIL", "CALL", "CALENDAR_EVENT", "SUPPORT_TICKET"]
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
},
|
|
2051
|
+
required: ["query"],
|
|
2052
|
+
additionalProperties: false
|
|
2053
|
+
}
|
|
2054
|
+
},
|
|
2055
|
+
outlit_query: {
|
|
2056
|
+
toolName: "outlit_query",
|
|
2057
|
+
description: `Execute raw SQL queries against your analytics data.
|
|
2058
|
+
|
|
2059
|
+
Available tables:
|
|
2060
|
+
- events: Customer activity events (event_type, event_channel, customer_id, occurred_at, properties, ...)
|
|
2061
|
+
- customer_dimensions: Customer attributes (customer_id, domain, name, billing_status, plan, mrr_cents, ...)
|
|
2062
|
+
- user_dimensions: User attributes (user_id, email, name, customer_id, ...)
|
|
2063
|
+
- mrr_snapshots: Revenue snapshots over time (customer_id, snapshot_date, mrr_cents, ...)
|
|
2064
|
+
|
|
2065
|
+
All queries are automatically filtered to your organization's data.
|
|
2066
|
+
Only SELECT queries are allowed.
|
|
2067
|
+
|
|
2068
|
+
Example queries:
|
|
2069
|
+
- SELECT event_type, count(*) FROM events GROUP BY 1 ORDER BY 2 DESC LIMIT 10
|
|
2070
|
+
- SELECT billing_status, sum(mrr_cents)/100 as mrr FROM customer_dimensions GROUP BY 1
|
|
2071
|
+
- SELECT * FROM events WHERE customer_id = 'cust_123' ORDER BY occurred_at DESC LIMIT 50`,
|
|
2072
|
+
inputSchema: {
|
|
2073
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
2074
|
+
type: "object",
|
|
2075
|
+
properties: {
|
|
2076
|
+
sql: {
|
|
2077
|
+
type: "string",
|
|
2078
|
+
description: "SQL SELECT query to execute"
|
|
2079
|
+
},
|
|
2080
|
+
limit: {
|
|
2081
|
+
description: "Max rows to return (default 1000, max 10000)",
|
|
2082
|
+
default: 1000,
|
|
2083
|
+
type: "number",
|
|
2084
|
+
maximum: 1e4
|
|
2085
|
+
}
|
|
2086
|
+
},
|
|
2087
|
+
required: ["sql"],
|
|
2088
|
+
additionalProperties: false
|
|
2089
|
+
}
|
|
2090
|
+
},
|
|
2091
|
+
outlit_schema: {
|
|
2092
|
+
toolName: "outlit_schema",
|
|
2093
|
+
description: `Get table schemas for available analytics tables.
|
|
2094
|
+
|
|
2095
|
+
Use this to discover column names, types, and descriptions before writing SQL queries.
|
|
2096
|
+
Returns column definitions and example queries for each table.`,
|
|
2097
|
+
inputSchema: {
|
|
2098
|
+
$schema: "https://json-schema.org/draft/2020-12/schema",
|
|
2099
|
+
type: "object",
|
|
2100
|
+
properties: {
|
|
2101
|
+
table: {
|
|
2102
|
+
description: "Specific table to describe, or omit for all tables",
|
|
2103
|
+
type: "string",
|
|
2104
|
+
enum: ["events", "customer_dimensions", "user_dimensions", "mrr_snapshots"]
|
|
2105
|
+
}
|
|
2106
|
+
},
|
|
2107
|
+
additionalProperties: false
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
};
|
|
2111
|
+
customerBillingStatuses = [
|
|
2112
|
+
"NONE",
|
|
2113
|
+
"TRIALING",
|
|
2114
|
+
"PAYING",
|
|
2115
|
+
"PAST_DUE",
|
|
2116
|
+
"CHURNED"
|
|
2117
|
+
];
|
|
2118
|
+
customerFactStatuses = [
|
|
2119
|
+
"ACTIVE",
|
|
2120
|
+
"ACKNOWLEDGED",
|
|
2121
|
+
"RESOLVED",
|
|
2122
|
+
"SNOOZED",
|
|
2123
|
+
"CANDIDATE"
|
|
2124
|
+
];
|
|
2125
|
+
customerFactTypes = [
|
|
2126
|
+
"CUSTOM",
|
|
2127
|
+
"COMPANY_CHANGE",
|
|
2128
|
+
"FUNDING_REVENUE",
|
|
2129
|
+
"TECHNOLOGY",
|
|
2130
|
+
"STRATEGY",
|
|
2131
|
+
"COMPETITIVE",
|
|
2132
|
+
"SENTIMENT",
|
|
2133
|
+
"CHAMPION_RISK",
|
|
2134
|
+
"EXPANSION",
|
|
2135
|
+
"CHURN_RISK",
|
|
2136
|
+
"TIMELINE",
|
|
2137
|
+
"BUDGET",
|
|
2138
|
+
"DECISION_MAKER",
|
|
2139
|
+
"REQUIREMENTS",
|
|
2140
|
+
"PRODUCT_USAGE",
|
|
2141
|
+
"CONTACT_INFO",
|
|
2142
|
+
"CONTACT_PREFERENCE"
|
|
2143
|
+
];
|
|
2144
|
+
unsupportedCustomerFactTypes = [
|
|
2145
|
+
"TRACKING_GAP",
|
|
2146
|
+
"SCHEMA_DRIFT",
|
|
2147
|
+
"INGESTION_LAG",
|
|
2148
|
+
"ACTIVATION_RATE_DROP",
|
|
2149
|
+
"FUNNEL_DROPOFF",
|
|
2150
|
+
"CORE_ACTION_DECAY",
|
|
2151
|
+
"CADENCE_BREAK",
|
|
2152
|
+
"QUIET_ACCOUNT",
|
|
2153
|
+
"CHAMPION_AT_RISK",
|
|
2154
|
+
"SEGMENT_DIVERGENCE"
|
|
2155
|
+
];
|
|
2156
|
+
customerFactCategories = ["MEMORY", "CUSTOM"];
|
|
2157
|
+
customerIncludeSections = [
|
|
2158
|
+
"users",
|
|
2159
|
+
"revenue",
|
|
2160
|
+
"recentTimeline",
|
|
2161
|
+
"behaviorMetrics"
|
|
2162
|
+
];
|
|
2163
|
+
customerSourceTypes = ["EMAIL", "CALL", "CALENDAR_EVENT", "SUPPORT_TICKET"];
|
|
2164
|
+
customerTimeframes = ["7d", "14d", "30d", "90d"];
|
|
2165
|
+
timelineChannels = [
|
|
2166
|
+
"SDK",
|
|
2167
|
+
"EMAIL",
|
|
2168
|
+
"SLACK",
|
|
2169
|
+
"CALL",
|
|
2170
|
+
"CRM",
|
|
2171
|
+
"BILLING",
|
|
2172
|
+
"SUPPORT",
|
|
2173
|
+
"INTERNAL"
|
|
2174
|
+
];
|
|
2175
|
+
timelineTimeframes = ["7d", "14d", "30d", "90d", "all"];
|
|
2176
|
+
userJourneyStages = [
|
|
2177
|
+
"DISCOVERED",
|
|
2178
|
+
"SIGNED_UP",
|
|
2179
|
+
"ACTIVATED",
|
|
2180
|
+
"ENGAGED",
|
|
2181
|
+
"INACTIVE"
|
|
2182
|
+
];
|
|
2183
|
+
schemaTables = [
|
|
2184
|
+
"events",
|
|
2185
|
+
"customer_dimensions",
|
|
2186
|
+
"user_dimensions",
|
|
2187
|
+
"mrr_snapshots"
|
|
2188
|
+
];
|
|
2189
|
+
customerToolNameSet = new Set(customerToolNames);
|
|
2190
|
+
iso8601UtcDateTimeRegex = /^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$/;
|
|
2191
|
+
defaultAgentToolNames = [
|
|
2192
|
+
"outlit_list_customers",
|
|
2193
|
+
"outlit_list_users",
|
|
2194
|
+
"outlit_get_customer",
|
|
2195
|
+
"outlit_get_timeline",
|
|
2196
|
+
"outlit_list_facts",
|
|
2197
|
+
"outlit_get_fact",
|
|
2198
|
+
"outlit_get_source",
|
|
2199
|
+
"outlit_search_customer_context"
|
|
2200
|
+
];
|
|
2201
|
+
sqlToolNames = [
|
|
2202
|
+
"outlit_schema",
|
|
2203
|
+
"outlit_query"
|
|
2204
|
+
];
|
|
2205
|
+
analyticalAgentToolNames = [
|
|
2206
|
+
...defaultAgentToolNames,
|
|
2207
|
+
...sqlToolNames
|
|
2208
|
+
];
|
|
2209
|
+
});
|
|
2210
|
+
|
|
1491
2211
|
// src/lib/client.ts
|
|
1492
2212
|
function buildUrl(base, path, params) {
|
|
1493
2213
|
const url = new URL(path, base);
|
|
@@ -1513,11 +2233,18 @@ async function createClient(flagApiKey) {
|
|
|
1513
2233
|
throw new Error(`Invalid API key format. Keys must start with "ok_" followed by at least 32 alphanumeric characters. Get one at ${OUTLIT_DASHBOARD_URL}`);
|
|
1514
2234
|
}
|
|
1515
2235
|
const baseUrl = process.env.OUTLIT_API_URL ?? DEFAULT_API_URL;
|
|
2236
|
+
const toolsClient = createOutlitClient({
|
|
2237
|
+
apiKey: credential.key,
|
|
2238
|
+
baseUrl
|
|
2239
|
+
});
|
|
1516
2240
|
return {
|
|
1517
2241
|
key: credential.key,
|
|
1518
2242
|
baseUrl,
|
|
1519
2243
|
async callTool(toolName, params) {
|
|
1520
|
-
|
|
2244
|
+
if (isCustomerToolName(toolName)) {
|
|
2245
|
+
return toolsClient.callTool(toolName, params);
|
|
2246
|
+
}
|
|
2247
|
+
const endpoint = CLI_TOOL_ENDPOINTS[toolName];
|
|
1521
2248
|
if (!endpoint) {
|
|
1522
2249
|
throw new Error(`Unknown tool: ${toolName}`);
|
|
1523
2250
|
}
|
|
@@ -1546,31 +2273,22 @@ async function createClient(flagApiKey) {
|
|
|
1546
2273
|
}
|
|
1547
2274
|
};
|
|
1548
2275
|
}
|
|
1549
|
-
var API_KEY_REGEX,
|
|
2276
|
+
var API_KEY_REGEX, CLI_TOOL_ENDPOINTS;
|
|
1550
2277
|
var init_client = __esm(() => {
|
|
2278
|
+
init_dist4();
|
|
1551
2279
|
init_config();
|
|
1552
2280
|
API_KEY_REGEX = /^ok_[A-Za-z0-9_-]{32,}$/;
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
outlit_get_timeline: { method: "POST", path: "/api/internal/mcp/timeline" },
|
|
1558
|
-
outlit_list_facts: { method: "POST", path: "/api/internal/mcp/facts" },
|
|
1559
|
-
outlit_get_fact: { method: "POST", path: "/api/internal/mcp/facts/get" },
|
|
1560
|
-
outlit_get_source: { method: "POST", path: "/api/internal/mcp/context-source" },
|
|
1561
|
-
outlit_schema: { method: "GET", path: "/api/internal/mcp/sql-schema" },
|
|
1562
|
-
outlit_query: { method: "POST", path: "/api/internal/mcp/sql" },
|
|
1563
|
-
outlit_search_customer_context: { method: "POST", path: "/api/internal/mcp/context-search" },
|
|
1564
|
-
outlit_list_integrations: { method: "GET", path: "/api/internal/mcp/integrations" },
|
|
1565
|
-
outlit_connect_integration: { method: "POST", path: "/api/internal/mcp/integrations/connect" },
|
|
1566
|
-
outlit_connect_status: { method: "GET", path: "/api/internal/mcp/integrations/connect/status" },
|
|
2281
|
+
CLI_TOOL_ENDPOINTS = {
|
|
2282
|
+
outlit_list_integrations: { method: "GET", path: "/api/integrations" },
|
|
2283
|
+
outlit_connect_integration: { method: "POST", path: "/api/integrations/connect" },
|
|
2284
|
+
outlit_connect_status: { method: "GET", path: "/api/integrations/connect/status" },
|
|
1567
2285
|
outlit_disconnect_integration: {
|
|
1568
2286
|
method: "POST",
|
|
1569
|
-
path: "/api/
|
|
2287
|
+
path: "/api/integrations/disconnect"
|
|
1570
2288
|
},
|
|
1571
2289
|
outlit_integration_sync_status: {
|
|
1572
2290
|
method: "GET",
|
|
1573
|
-
path: "/api/
|
|
2291
|
+
path: "/api/integrations/sync-status"
|
|
1574
2292
|
}
|
|
1575
2293
|
};
|
|
1576
2294
|
});
|
|
@@ -1700,7 +2418,7 @@ async function getClientOrExit(flagApiKey, json) {
|
|
|
1700
2418
|
}
|
|
1701
2419
|
async function pingApiKey(apiKey) {
|
|
1702
2420
|
const baseUrl = process.env.OUTLIT_API_URL ?? DEFAULT_API_URL;
|
|
1703
|
-
const url = new URL("/api/
|
|
2421
|
+
const url = new URL("/api/validate-api-key", baseUrl).toString();
|
|
1704
2422
|
const response = await globalThis.fetch(url, {
|
|
1705
2423
|
method: "POST",
|
|
1706
2424
|
headers: {
|
|
@@ -2201,148 +2919,6 @@ Use this to fetch the next page of results.`
|
|
|
2201
2919
|
};
|
|
2202
2920
|
});
|
|
2203
2921
|
|
|
2204
|
-
// src/generated/tool-contracts.ts
|
|
2205
|
-
function resolveCustomerContextSearchInput(value) {
|
|
2206
|
-
if (!value.query) {
|
|
2207
|
-
return {
|
|
2208
|
-
ok: false,
|
|
2209
|
-
message: "A query argument is required"
|
|
2210
|
-
};
|
|
2211
|
-
}
|
|
2212
|
-
const normalizedQuery = value.query.trim();
|
|
2213
|
-
if (normalizedQuery.length < 2) {
|
|
2214
|
-
return {
|
|
2215
|
-
ok: false,
|
|
2216
|
-
message: "Query must be at least 2 non-whitespace characters"
|
|
2217
|
-
};
|
|
2218
|
-
}
|
|
2219
|
-
if (value.after !== undefined && value.before !== undefined && new Date(value.after).getTime() > new Date(value.before).getTime()) {
|
|
2220
|
-
return {
|
|
2221
|
-
ok: false,
|
|
2222
|
-
message: "--after must be before or equal to --before"
|
|
2223
|
-
};
|
|
2224
|
-
}
|
|
2225
|
-
return {
|
|
2226
|
-
ok: true,
|
|
2227
|
-
request: {
|
|
2228
|
-
query: normalizedQuery,
|
|
2229
|
-
customer: value.customer,
|
|
2230
|
-
topK: value.topK,
|
|
2231
|
-
after: value.after,
|
|
2232
|
-
before: value.before,
|
|
2233
|
-
sourceTypes: value.sourceTypes
|
|
2234
|
-
}
|
|
2235
|
-
};
|
|
2236
|
-
}
|
|
2237
|
-
var customerToolContracts, customerBillingStatuses, customerFactStatuses, customerIncludeSections, customerSourceTypes, customerTimeframes, timelineChannels, timelineTimeframes, userJourneyStages, schemaTables;
|
|
2238
|
-
var init_tool_contracts = __esm(() => {
|
|
2239
|
-
customerToolContracts = {
|
|
2240
|
-
outlit_list_customers: {
|
|
2241
|
-
toolName: "outlit_list_customers",
|
|
2242
|
-
description: "Browse and filter customers. Use this to find customers by billing status, activity recency, revenue, or name. Returns a paginated list with summary info (MRR, last activity, status)."
|
|
2243
|
-
},
|
|
2244
|
-
outlit_list_users: {
|
|
2245
|
-
toolName: "outlit_list_users",
|
|
2246
|
-
description: "Browse and filter users. Use this to find users by journey stage, activity recency, customer, or email/name. Returns a paginated list with activity info."
|
|
2247
|
-
},
|
|
2248
|
-
outlit_get_customer: {
|
|
2249
|
-
toolName: "outlit_get_customer",
|
|
2250
|
-
description: "Get full details for a single customer. Use this when you already know which customer you want to inspect. Optionally include related data (users, revenue, recent activity, engagement metrics)."
|
|
2251
|
-
},
|
|
2252
|
-
outlit_get_timeline: {
|
|
2253
|
-
toolName: "outlit_get_timeline",
|
|
2254
|
-
description: "Get the chronological activity timeline for a customer. Use this to see what happened and when — emails, calls, Slack messages, billing events, etc. Supports channel and date filtering."
|
|
2255
|
-
},
|
|
2256
|
-
outlit_list_facts: {
|
|
2257
|
-
toolName: "outlit_list_facts",
|
|
2258
|
-
description: "List structured facts known about a customer. Use filters like status, sourceTypes, and date bounds to narrow the result set. For topic-specific retrieval, use outlit_search_customer_context instead."
|
|
2259
|
-
},
|
|
2260
|
-
outlit_get_fact: {
|
|
2261
|
-
toolName: "outlit_get_fact",
|
|
2262
|
-
description: "Get one exact fact by ID. Returns the canonical fact shape and optionally expands requested related data such as evidence."
|
|
2263
|
-
},
|
|
2264
|
-
outlit_get_source: {
|
|
2265
|
-
toolName: "outlit_get_source",
|
|
2266
|
-
description: "Get one exact source record by generic sourceType and sourceId. Use this when you already know the concrete underlying source you want to inspect."
|
|
2267
|
-
},
|
|
2268
|
-
outlit_search_customer_context: {
|
|
2269
|
-
toolName: "outlit_search_customer_context",
|
|
2270
|
-
description: "Search across all known customer context using a natural-language query. Returns grouped artifact-level results for matching sources and facts. Omit customer to search across all customers in the organization."
|
|
2271
|
-
},
|
|
2272
|
-
outlit_query: {
|
|
2273
|
-
toolName: "outlit_query",
|
|
2274
|
-
description: `Execute raw SQL queries against your analytics data.
|
|
2275
|
-
|
|
2276
|
-
Available tables:
|
|
2277
|
-
- events: Customer activity events (event_type, event_channel, customer_id, occurred_at, properties, ...)
|
|
2278
|
-
- customer_dimensions: Customer attributes (customer_id, domain, name, billing_status, plan, mrr_cents, ...)
|
|
2279
|
-
- user_dimensions: User attributes (user_id, email, name, customer_id, ...)
|
|
2280
|
-
- mrr_snapshots: Revenue snapshots over time (customer_id, snapshot_date, mrr_cents, ...)
|
|
2281
|
-
|
|
2282
|
-
All queries are automatically filtered to your organization's data.
|
|
2283
|
-
Only SELECT queries are allowed.
|
|
2284
|
-
|
|
2285
|
-
Example queries:
|
|
2286
|
-
- SELECT event_type, count(*) FROM events GROUP BY 1 ORDER BY 2 DESC LIMIT 10
|
|
2287
|
-
- SELECT billing_status, sum(mrr_cents)/100 as mrr FROM customer_dimensions GROUP BY 1
|
|
2288
|
-
- SELECT * FROM events WHERE customer_id = 'cust_123' ORDER BY occurred_at DESC LIMIT 50`
|
|
2289
|
-
},
|
|
2290
|
-
outlit_schema: {
|
|
2291
|
-
toolName: "outlit_schema",
|
|
2292
|
-
description: `Get table schemas for available analytics tables.
|
|
2293
|
-
|
|
2294
|
-
Use this to discover column names, types, and descriptions before writing SQL queries.
|
|
2295
|
-
Returns column definitions and example queries for each table.`
|
|
2296
|
-
}
|
|
2297
|
-
};
|
|
2298
|
-
customerBillingStatuses = [
|
|
2299
|
-
"NONE",
|
|
2300
|
-
"TRIALING",
|
|
2301
|
-
"PAYING",
|
|
2302
|
-
"PAST_DUE",
|
|
2303
|
-
"CHURNED"
|
|
2304
|
-
];
|
|
2305
|
-
customerFactStatuses = [
|
|
2306
|
-
"ACTIVE",
|
|
2307
|
-
"ACKNOWLEDGED",
|
|
2308
|
-
"RESOLVED",
|
|
2309
|
-
"SNOOZED",
|
|
2310
|
-
"CANDIDATE"
|
|
2311
|
-
];
|
|
2312
|
-
customerIncludeSections = [
|
|
2313
|
-
"users",
|
|
2314
|
-
"revenue",
|
|
2315
|
-
"recentTimeline",
|
|
2316
|
-
"behaviorMetrics"
|
|
2317
|
-
];
|
|
2318
|
-
customerSourceTypes = ["EMAIL", "CALL", "CALENDAR_EVENT", "SUPPORT_TICKET"];
|
|
2319
|
-
customerTimeframes = ["7d", "14d", "30d", "90d"];
|
|
2320
|
-
timelineChannels = [
|
|
2321
|
-
"SDK",
|
|
2322
|
-
"EMAIL",
|
|
2323
|
-
"SLACK",
|
|
2324
|
-
"CALL",
|
|
2325
|
-
"CRM",
|
|
2326
|
-
"BILLING",
|
|
2327
|
-
"SUPPORT",
|
|
2328
|
-
"INTERNAL"
|
|
2329
|
-
];
|
|
2330
|
-
timelineTimeframes = ["7d", "14d", "30d", "90d", "all"];
|
|
2331
|
-
userJourneyStages = [
|
|
2332
|
-
"DISCOVERED",
|
|
2333
|
-
"SIGNED_UP",
|
|
2334
|
-
"ACTIVATED",
|
|
2335
|
-
"ENGAGED",
|
|
2336
|
-
"INACTIVE"
|
|
2337
|
-
];
|
|
2338
|
-
schemaTables = [
|
|
2339
|
-
"events",
|
|
2340
|
-
"customer_dimensions",
|
|
2341
|
-
"user_dimensions",
|
|
2342
|
-
"mrr_snapshots"
|
|
2343
|
-
];
|
|
2344
|
-
});
|
|
2345
|
-
|
|
2346
2922
|
// src/lib/format.ts
|
|
2347
2923
|
function formatCents(value) {
|
|
2348
2924
|
if (value == null || typeof value !== "number" || Number.isNaN(value))
|
|
@@ -2401,12 +2977,12 @@ __export(exports_list, {
|
|
|
2401
2977
|
});
|
|
2402
2978
|
var list_default;
|
|
2403
2979
|
var init_list = __esm(() => {
|
|
2980
|
+
init_dist4();
|
|
2404
2981
|
init_dist();
|
|
2405
2982
|
init_auth();
|
|
2406
2983
|
init_filters();
|
|
2407
2984
|
init_output2();
|
|
2408
2985
|
init_pagination();
|
|
2409
|
-
init_tool_contracts();
|
|
2410
2986
|
init_api();
|
|
2411
2987
|
init_output();
|
|
2412
2988
|
list_default = defineCommand2({
|
|
@@ -2514,10 +3090,10 @@ __export(exports_get, {
|
|
|
2514
3090
|
});
|
|
2515
3091
|
var get_default;
|
|
2516
3092
|
var init_get = __esm(() => {
|
|
3093
|
+
init_dist4();
|
|
2517
3094
|
init_dist();
|
|
2518
3095
|
init_auth();
|
|
2519
3096
|
init_output2();
|
|
2520
|
-
init_tool_contracts();
|
|
2521
3097
|
init_api();
|
|
2522
3098
|
init_config();
|
|
2523
3099
|
get_default = defineCommand2({
|
|
@@ -2591,11 +3167,11 @@ __export(exports_timeline, {
|
|
|
2591
3167
|
});
|
|
2592
3168
|
var timeline_default;
|
|
2593
3169
|
var init_timeline = __esm(() => {
|
|
3170
|
+
init_dist4();
|
|
2594
3171
|
init_dist();
|
|
2595
3172
|
init_auth();
|
|
2596
3173
|
init_output2();
|
|
2597
3174
|
init_pagination();
|
|
2598
|
-
init_tool_contracts();
|
|
2599
3175
|
init_api();
|
|
2600
3176
|
init_config();
|
|
2601
3177
|
timeline_default = defineCommand2({
|
|
@@ -2617,7 +3193,7 @@ var init_timeline = __esm(() => {
|
|
|
2617
3193
|
" outlit customers timeline acme.com",
|
|
2618
3194
|
" outlit customers timeline acme.com --timeframe 90d",
|
|
2619
3195
|
" outlit customers timeline acme.com --channels EMAIL,SLACK",
|
|
2620
|
-
" outlit customers timeline acme.com --start-date 2025-01-
|
|
3196
|
+
" outlit customers timeline acme.com --start-date 2025-01-01T00:00:00Z --end-date 2025-03-01T23:59:59Z",
|
|
2621
3197
|
" outlit customers timeline acme.com --event-types PAGE_VIEW,MEETING --limit 50",
|
|
2622
3198
|
"",
|
|
2623
3199
|
AGENT_JSON_HINT
|
|
@@ -2648,11 +3224,11 @@ var init_timeline = __esm(() => {
|
|
|
2648
3224
|
},
|
|
2649
3225
|
"start-date": {
|
|
2650
3226
|
type: "string",
|
|
2651
|
-
description: "Start
|
|
3227
|
+
description: "Start datetime for the event range (ISO 8601, e.g. 2025-01-01T00:00:00Z). When set, --timeframe is ignored."
|
|
2652
3228
|
},
|
|
2653
3229
|
"end-date": {
|
|
2654
3230
|
type: "string",
|
|
2655
|
-
description: "End
|
|
3231
|
+
description: "End datetime for the event range (ISO 8601, e.g. 2025-03-01T23:59:59Z). When set, --timeframe is ignored."
|
|
2656
3232
|
}
|
|
2657
3233
|
},
|
|
2658
3234
|
async run({ args }) {
|
|
@@ -2719,12 +3295,12 @@ __export(exports_list2, {
|
|
|
2719
3295
|
});
|
|
2720
3296
|
var list_default2;
|
|
2721
3297
|
var init_list2 = __esm(() => {
|
|
3298
|
+
init_dist4();
|
|
2722
3299
|
init_dist();
|
|
2723
3300
|
init_auth();
|
|
2724
3301
|
init_filters();
|
|
2725
3302
|
init_output2();
|
|
2726
3303
|
init_pagination();
|
|
2727
|
-
init_tool_contracts();
|
|
2728
3304
|
init_api();
|
|
2729
3305
|
init_output();
|
|
2730
3306
|
list_default2 = defineCommand2({
|
|
@@ -3797,11 +4373,11 @@ function invalidValues(values, allowed) {
|
|
|
3797
4373
|
}
|
|
3798
4374
|
var list_default3;
|
|
3799
4375
|
var init_list3 = __esm(() => {
|
|
4376
|
+
init_dist4();
|
|
3800
4377
|
init_dist();
|
|
3801
4378
|
init_auth();
|
|
3802
4379
|
init_output2();
|
|
3803
4380
|
init_pagination();
|
|
3804
|
-
init_tool_contracts();
|
|
3805
4381
|
init_api();
|
|
3806
4382
|
init_config();
|
|
3807
4383
|
init_output();
|
|
@@ -3816,11 +4392,13 @@ var init_list3 = __esm(() => {
|
|
|
3816
4392
|
"Examples:",
|
|
3817
4393
|
" outlit facts list acme.com",
|
|
3818
4394
|
" outlit facts list acme.com --status ACTIVE",
|
|
4395
|
+
" outlit facts list acme.com --fact-types CHURN_RISK,EXPANSION",
|
|
3819
4396
|
" outlit facts list acme.com --source-types CALL,EMAIL --after 2025-01-01T00:00:00Z",
|
|
3820
4397
|
" outlit facts list acme.com --limit 50 --json",
|
|
3821
4398
|
"",
|
|
3822
4399
|
`Statuses: ${customerFactStatuses.join(", ")}`,
|
|
3823
4400
|
`Source types: ${customerSourceTypes.join(", ")}`,
|
|
4401
|
+
`Fact categories: ${customerFactCategories.join(", ")}`,
|
|
3824
4402
|
"",
|
|
3825
4403
|
AGENT_JSON_HINT
|
|
3826
4404
|
].join(`
|
|
@@ -3843,6 +4421,14 @@ var init_list3 = __esm(() => {
|
|
|
3843
4421
|
type: "string",
|
|
3844
4422
|
description: `Comma-separated generic source type filter (${customerSourceTypes.join(", ")})`
|
|
3845
4423
|
},
|
|
4424
|
+
"fact-types": {
|
|
4425
|
+
type: "string",
|
|
4426
|
+
description: "Comma-separated customer-memory fact type filter, such as CHURN_RISK, EXPANSION, or SENTIMENT"
|
|
4427
|
+
},
|
|
4428
|
+
"fact-categories": {
|
|
4429
|
+
type: "string",
|
|
4430
|
+
description: `Comma-separated fact category filter (${customerFactCategories.join(", ")})`
|
|
4431
|
+
},
|
|
3846
4432
|
after: {
|
|
3847
4433
|
type: "string",
|
|
3848
4434
|
description: "Filter to facts occurring after this ISO 8601 datetime"
|
|
@@ -3856,6 +4442,8 @@ var init_list3 = __esm(() => {
|
|
|
3856
4442
|
const json = !!args.json;
|
|
3857
4443
|
const statuses = parseCsvArg(args.status);
|
|
3858
4444
|
const sourceTypes = parseCsvArg(args["source-types"]);
|
|
4445
|
+
const factTypes = parseCsvArg(args["fact-types"]);
|
|
4446
|
+
const factCategories = parseCsvArg(args["fact-categories"]);
|
|
3859
4447
|
const invalidStatuses = invalidValues(statuses, customerFactStatuses);
|
|
3860
4448
|
if (invalidStatuses.length > 0) {
|
|
3861
4449
|
return outputError({
|
|
@@ -3870,6 +4458,29 @@ var init_list3 = __esm(() => {
|
|
|
3870
4458
|
code: "invalid_input"
|
|
3871
4459
|
}, json);
|
|
3872
4460
|
}
|
|
4461
|
+
const invalidFactTypes = invalidValues(factTypes, customerFactTypes);
|
|
4462
|
+
if (invalidFactTypes.length > 0) {
|
|
4463
|
+
const anomalyFactTypes = invalidFactTypes.filter((value) => unsupportedCustomerFactTypes.includes(value));
|
|
4464
|
+
const unknownFactTypes = invalidFactTypes.filter((value) => !unsupportedCustomerFactTypes.includes(value));
|
|
4465
|
+
const messageParts = [];
|
|
4466
|
+
if (anomalyFactTypes.length > 0) {
|
|
4467
|
+
messageParts.push(`Anomaly detector fact types are not supported as public filters: ${anomalyFactTypes.join(", ")}. Use customer-memory fact types such as CHURN_RISK, EXPANSION, SENTIMENT, or PRODUCT_USAGE.`);
|
|
4468
|
+
}
|
|
4469
|
+
if (unknownFactTypes.length > 0) {
|
|
4470
|
+
messageParts.push(`Unknown fact types: ${unknownFactTypes.join(", ")}. Allowed: ${customerFactTypes.join(", ")}`);
|
|
4471
|
+
}
|
|
4472
|
+
return outputError({
|
|
4473
|
+
message: messageParts.join(" "),
|
|
4474
|
+
code: "invalid_input"
|
|
4475
|
+
}, json);
|
|
4476
|
+
}
|
|
4477
|
+
const invalidFactCategories = invalidValues(factCategories, customerFactCategories);
|
|
4478
|
+
if (invalidFactCategories.length > 0) {
|
|
4479
|
+
return outputError({
|
|
4480
|
+
message: `Unsupported fact categories: ${invalidFactCategories.join(", ")}. Allowed: ${customerFactCategories.join(", ")}`,
|
|
4481
|
+
code: "invalid_input"
|
|
4482
|
+
}, json);
|
|
4483
|
+
}
|
|
3873
4484
|
const afterDate = args.after ? new Date(args.after) : null;
|
|
3874
4485
|
const beforeDate = args.before ? new Date(args.before) : null;
|
|
3875
4486
|
if (afterDate && Number.isNaN(afterDate.getTime())) {
|
|
@@ -3898,6 +4509,10 @@ var init_list3 = __esm(() => {
|
|
|
3898
4509
|
params.status = statuses;
|
|
3899
4510
|
if (sourceTypes)
|
|
3900
4511
|
params.sourceTypes = sourceTypes;
|
|
4512
|
+
if (factTypes)
|
|
4513
|
+
params.factTypes = factTypes;
|
|
4514
|
+
if (factCategories)
|
|
4515
|
+
params.factCategories = factCategories;
|
|
3901
4516
|
if (args.after)
|
|
3902
4517
|
params.after = args.after;
|
|
3903
4518
|
if (args.before)
|
|
@@ -3921,10 +4536,10 @@ function parseCsvArg2(value) {
|
|
|
3921
4536
|
}
|
|
3922
4537
|
var get_default2;
|
|
3923
4538
|
var init_get2 = __esm(() => {
|
|
4539
|
+
init_dist4();
|
|
3924
4540
|
init_dist();
|
|
3925
4541
|
init_auth();
|
|
3926
4542
|
init_output2();
|
|
3927
|
-
init_tool_contracts();
|
|
3928
4543
|
init_api();
|
|
3929
4544
|
init_config();
|
|
3930
4545
|
get_default2 = defineCommand2({
|
|
@@ -4007,10 +4622,10 @@ __export(exports_get3, {
|
|
|
4007
4622
|
});
|
|
4008
4623
|
var get_default3;
|
|
4009
4624
|
var init_get3 = __esm(() => {
|
|
4625
|
+
init_dist4();
|
|
4010
4626
|
init_dist();
|
|
4011
4627
|
init_auth();
|
|
4012
4628
|
init_output2();
|
|
4013
|
-
init_tool_contracts();
|
|
4014
4629
|
init_api();
|
|
4015
4630
|
init_output();
|
|
4016
4631
|
get_default3 = defineCommand2({
|
|
@@ -4095,10 +4710,10 @@ __export(exports_search, {
|
|
|
4095
4710
|
});
|
|
4096
4711
|
var search_default;
|
|
4097
4712
|
var init_search = __esm(() => {
|
|
4713
|
+
init_dist4();
|
|
4098
4714
|
init_dist();
|
|
4099
4715
|
init_auth();
|
|
4100
4716
|
init_output2();
|
|
4101
|
-
init_tool_contracts();
|
|
4102
4717
|
init_api();
|
|
4103
4718
|
init_config();
|
|
4104
4719
|
init_output();
|
|
@@ -4193,10 +4808,10 @@ __export(exports_sql, {
|
|
|
4193
4808
|
import { readFileSync as readFileSync4 } from "node:fs";
|
|
4194
4809
|
var sql_default;
|
|
4195
4810
|
var init_sql = __esm(() => {
|
|
4811
|
+
init_dist4();
|
|
4196
4812
|
init_dist();
|
|
4197
4813
|
init_auth();
|
|
4198
4814
|
init_output2();
|
|
4199
|
-
init_tool_contracts();
|
|
4200
4815
|
init_api();
|
|
4201
4816
|
init_output();
|
|
4202
4817
|
sql_default = defineCommand2({
|
|
@@ -4271,10 +4886,10 @@ __export(exports_schema, {
|
|
|
4271
4886
|
});
|
|
4272
4887
|
var schema_default;
|
|
4273
4888
|
var init_schema = __esm(() => {
|
|
4889
|
+
init_dist4();
|
|
4274
4890
|
init_dist();
|
|
4275
4891
|
init_auth();
|
|
4276
4892
|
init_output2();
|
|
4277
|
-
init_tool_contracts();
|
|
4278
4893
|
init_api();
|
|
4279
4894
|
schema_default = defineCommand2({
|
|
4280
4895
|
meta: {
|
|
@@ -5181,6 +5796,8 @@ var init_completions = __esm(() => {
|
|
|
5181
5796
|
...PAGINATED,
|
|
5182
5797
|
{ name: "--status", desc: "Filter by fact status" },
|
|
5183
5798
|
{ name: "--source-types", desc: "Filter by source types" },
|
|
5799
|
+
{ name: "--fact-types", desc: "Filter by fact types" },
|
|
5800
|
+
{ name: "--fact-categories", desc: "Filter by fact categories" },
|
|
5184
5801
|
{ name: "--after", desc: "Facts after date (ISO 8601)" },
|
|
5185
5802
|
{ name: "--before", desc: "Facts before date (ISO 8601)" }
|
|
5186
5803
|
]
|
|
@@ -6053,7 +6670,7 @@ Usage examples:
|
|
|
6053
6670
|
outlit customers get acme.com --include users,revenue
|
|
6054
6671
|
outlit customers timeline acme.com --timeframe 90d
|
|
6055
6672
|
outlit users list --journey-stage CHAMPION
|
|
6056
|
-
outlit facts list acme.com --
|
|
6673
|
+
outlit facts list acme.com --fact-types CHURN_RISK,EXPANSION
|
|
6057
6674
|
outlit facts get --fact-id fact_123 --include evidence
|
|
6058
6675
|
outlit sources get --source-type CALL --source-id call_123
|
|
6059
6676
|
outlit search 'pricing objections last quarter' --source-types CALL,EMAIL
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@outlit/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "CLI for Outlit customer intelligence platform",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -30,8 +30,9 @@
|
|
|
30
30
|
"typecheck": "tsc --noEmit"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"
|
|
34
|
-
"@
|
|
33
|
+
"@clack/prompts": "^1.0.1",
|
|
34
|
+
"@outlit/tools": "^0.1.0",
|
|
35
|
+
"citty": "^0.2.1"
|
|
35
36
|
},
|
|
36
37
|
"devDependencies": {
|
|
37
38
|
"typescript": "^5.9.3",
|