@wisewandtools/mcp-server 2.2.0 → 2.2.3
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/index.js +426 -166
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1169,6 +1169,63 @@ var HealthChecker = class {
|
|
|
1169
1169
|
|
|
1170
1170
|
// src/handlers/tools/ArticleToolHandler.ts
|
|
1171
1171
|
import { z as z2 } from "zod";
|
|
1172
|
+
|
|
1173
|
+
// src/utils/tool-helpers.ts
|
|
1174
|
+
var UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
1175
|
+
var ToolInputError = class extends Error {
|
|
1176
|
+
static {
|
|
1177
|
+
__name(this, "ToolInputError");
|
|
1178
|
+
}
|
|
1179
|
+
constructor(message) {
|
|
1180
|
+
super(message);
|
|
1181
|
+
this.name = "ToolInputError";
|
|
1182
|
+
}
|
|
1183
|
+
};
|
|
1184
|
+
function resolveId(args, ...fallbackKeys) {
|
|
1185
|
+
const value = args.id ?? args.Id ?? args.ID;
|
|
1186
|
+
if (value !== void 0 && value !== null) {
|
|
1187
|
+
return validateUuid(value);
|
|
1188
|
+
}
|
|
1189
|
+
for (const key of fallbackKeys) {
|
|
1190
|
+
if (args[key] !== void 0 && args[key] !== null) {
|
|
1191
|
+
return validateUuid(args[key]);
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
const tried = ["id", ...fallbackKeys].join(", ");
|
|
1195
|
+
throw new ToolInputError(`Missing required ID. Provide one of: ${tried}`);
|
|
1196
|
+
}
|
|
1197
|
+
__name(resolveId, "resolveId");
|
|
1198
|
+
function validateUuid(value) {
|
|
1199
|
+
const str = String(value);
|
|
1200
|
+
if (!UUID_REGEX.test(str)) {
|
|
1201
|
+
throw new ToolInputError(`Invalid ID format: "${str}" is not a valid UUID`);
|
|
1202
|
+
}
|
|
1203
|
+
return str;
|
|
1204
|
+
}
|
|
1205
|
+
__name(validateUuid, "validateUuid");
|
|
1206
|
+
function resolveArray(args, key) {
|
|
1207
|
+
let value = args[key];
|
|
1208
|
+
if (value === void 0 || value === null) {
|
|
1209
|
+
throw new ToolInputError(`Missing required parameter: ${key}`);
|
|
1210
|
+
}
|
|
1211
|
+
if (typeof value === "string") {
|
|
1212
|
+
try {
|
|
1213
|
+
value = JSON.parse(value);
|
|
1214
|
+
} catch {
|
|
1215
|
+
throw new ToolInputError(`Invalid ${key} format: expected JSON array`);
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
if (!Array.isArray(value)) {
|
|
1219
|
+
throw new ToolInputError(`Invalid ${key} format: expected array, got ${typeof value}`);
|
|
1220
|
+
}
|
|
1221
|
+
if (value.length === 0) {
|
|
1222
|
+
throw new ToolInputError(`${key} must not be empty`);
|
|
1223
|
+
}
|
|
1224
|
+
return value;
|
|
1225
|
+
}
|
|
1226
|
+
__name(resolveArray, "resolveArray");
|
|
1227
|
+
|
|
1228
|
+
// src/handlers/tools/ArticleToolHandler.ts
|
|
1172
1229
|
var boolField = z2.union([z2.boolean(), z2.string()]).transform(
|
|
1173
1230
|
(val) => typeof val === "string" ? val === "true" : val
|
|
1174
1231
|
).optional().default(false);
|
|
@@ -1465,7 +1522,7 @@ var ArticleToolHandler = class {
|
|
|
1465
1522
|
publishwordpress_date: { type: "string", description: "WordPress publish date (ISO 8601)" },
|
|
1466
1523
|
publishwordpress_status: { type: "string", enum: ["draft", "publish", "future"], description: "WordPress post status", default: "draft" },
|
|
1467
1524
|
publishwordpress_category: { type: "number", description: "WordPress category ID" },
|
|
1468
|
-
publishwordpress_author: { type: "number", description: "WordPress author ID" },
|
|
1525
|
+
publishwordpress_author: { type: "number", description: "WordPress author ID. CAUTION: If the WP connection user lacks edit_others_posts capability, setting this will cause publishing to fail with rest_cannot_edit_others. Omit unless the WP user has admin/editor role." },
|
|
1469
1526
|
publishwordpress_connection: { type: "string", format: "uuid", description: "WordPress connection ID" },
|
|
1470
1527
|
// Shopify Publishing
|
|
1471
1528
|
use_publishshopify: { type: "boolean", description: "Automatically publish to Shopify" },
|
|
@@ -1537,21 +1594,38 @@ var ArticleToolHandler = class {
|
|
|
1537
1594
|
const validated = CreateArticleSchema.parse(args);
|
|
1538
1595
|
const apiInput = this.buildApiInput(validated);
|
|
1539
1596
|
const article = await this.apiClient.createArticle(apiInput);
|
|
1540
|
-
await this.cache.set(`article:${article.id}`, article, 300);
|
|
1541
1597
|
this.metrics.recordAPICall("create_article", "success");
|
|
1598
|
+
const warnings = [];
|
|
1599
|
+
if (validated.use_publishwordpress && !validated.publishwordpress_connection) {
|
|
1600
|
+
warnings.push("Warning: use_publishwordpress is true but publishwordpress_connection is not set. The article may not be published to WordPress. Provide a publishwordpress_connection UUID.");
|
|
1601
|
+
}
|
|
1602
|
+
if (validated.publishwordpress_author) {
|
|
1603
|
+
warnings.push(
|
|
1604
|
+
'Warning: publishwordpress_author is set. If the WP connection user lacks edit_others_posts capability, auto-publish will silently fail with "rest_cannot_edit_others". Omit publishwordpress_author unless the WP user has admin/editor role.'
|
|
1605
|
+
);
|
|
1606
|
+
}
|
|
1607
|
+
const hasAutoPublish = validated.use_publishwordpress || validated.use_publishshopify || validated.use_publishprestashop || validated.use_publishwoocommerce;
|
|
1608
|
+
const next_steps = hasAutoPublish ? [
|
|
1609
|
+
`Generation auto-triggered. Use 'get_article' with id: ${article.id} to check progress`,
|
|
1610
|
+
`Use 'get_article_output' with id: ${article.id} to get content once ready`
|
|
1611
|
+
] : [
|
|
1612
|
+
`Use 'generate_article' with id: ${article.id} to start content generation`,
|
|
1613
|
+
`Use 'get_article' with id: ${article.id} to check status`
|
|
1614
|
+
];
|
|
1615
|
+
const response = {
|
|
1616
|
+
success: true,
|
|
1617
|
+
article_id: article.id,
|
|
1618
|
+
title: article.title || "Article created",
|
|
1619
|
+
message: `Article "${article.title || validated.subject}" created successfully.`,
|
|
1620
|
+
next_steps
|
|
1621
|
+
};
|
|
1622
|
+
if (warnings.length > 0) {
|
|
1623
|
+
response.warnings = warnings;
|
|
1624
|
+
}
|
|
1542
1625
|
return {
|
|
1543
1626
|
content: [{
|
|
1544
1627
|
type: "text",
|
|
1545
|
-
text: JSON.stringify(
|
|
1546
|
-
success: true,
|
|
1547
|
-
article_id: article.id,
|
|
1548
|
-
title: article.title || "Article created",
|
|
1549
|
-
message: `Article "${article.title || validated.subject}" created successfully.`,
|
|
1550
|
-
next_steps: [
|
|
1551
|
-
`Use 'generate_article' with article_id: ${article.id} to start content generation`,
|
|
1552
|
-
`Use 'get_article' with article_id: ${article.id} to check status`
|
|
1553
|
-
]
|
|
1554
|
-
}, null, 2)
|
|
1628
|
+
text: JSON.stringify(response, null, 2)
|
|
1555
1629
|
}]
|
|
1556
1630
|
};
|
|
1557
1631
|
} catch (error) {
|
|
@@ -1572,15 +1646,16 @@ var ArticleToolHandler = class {
|
|
|
1572
1646
|
inputSchema: {
|
|
1573
1647
|
type: "object",
|
|
1574
1648
|
properties: {
|
|
1575
|
-
|
|
1649
|
+
id: { type: "string", format: "uuid", description: "ID of the article to generate" },
|
|
1576
1650
|
wait_for_completion: { type: "boolean", description: "Wait for generation to complete (may take several minutes)", default: true },
|
|
1577
1651
|
max_wait_time: { type: "number", description: "Maximum time to wait in seconds", default: 300, maximum: 600 }
|
|
1578
1652
|
},
|
|
1579
|
-
required: ["
|
|
1653
|
+
required: ["id"]
|
|
1580
1654
|
},
|
|
1581
1655
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
1582
1656
|
try {
|
|
1583
|
-
const
|
|
1657
|
+
const article_id = resolveId(args, "article_id");
|
|
1658
|
+
const { wait_for_completion = true, max_wait_time = 300 } = args;
|
|
1584
1659
|
await this.apiClient.runArticleGeneration(article_id);
|
|
1585
1660
|
if (!wait_for_completion) {
|
|
1586
1661
|
return { content: [{ type: "text", text: JSON.stringify({ success: true, message: "Article generation started", article_id, next_step: `Use 'get_article' or 'get_article_output' to check status` }, null, 2) }] };
|
|
@@ -1618,6 +1693,22 @@ var ArticleToolHandler = class {
|
|
|
1618
1693
|
}
|
|
1619
1694
|
throw new Error(`Generation timeout after ${max_wait_time} seconds`);
|
|
1620
1695
|
} catch (error) {
|
|
1696
|
+
const errorMsg = (error.message || "").toLowerCase();
|
|
1697
|
+
if (errorMsg.includes("already running") || errorMsg.includes("in queue") || errorMsg.includes("already in progress")) {
|
|
1698
|
+
const article_id = args.id || args.article_id;
|
|
1699
|
+
return {
|
|
1700
|
+
content: [{
|
|
1701
|
+
type: "text",
|
|
1702
|
+
text: JSON.stringify({
|
|
1703
|
+
success: true,
|
|
1704
|
+
article_id,
|
|
1705
|
+
status: "already_running",
|
|
1706
|
+
message: "Article generation is already in progress. Use get_article to check status.",
|
|
1707
|
+
next_steps: [`Use 'get_article' with id: ${article_id} to check progress`]
|
|
1708
|
+
}, null, 2)
|
|
1709
|
+
}]
|
|
1710
|
+
};
|
|
1711
|
+
}
|
|
1621
1712
|
logger.error("Failed to generate article", { error: error.message });
|
|
1622
1713
|
this.metrics.recordAPICall("generate_article", "error");
|
|
1623
1714
|
return { content: [{ type: "text", text: JSON.stringify({ error: true, message: error.message || "Failed to generate article" }, null, 2) }], isError: true };
|
|
@@ -1631,12 +1722,12 @@ var ArticleToolHandler = class {
|
|
|
1631
1722
|
description: "Get article details and status",
|
|
1632
1723
|
inputSchema: {
|
|
1633
1724
|
type: "object",
|
|
1634
|
-
properties: {
|
|
1635
|
-
required: ["
|
|
1725
|
+
properties: { id: { type: "string", format: "uuid", description: "ID of the article to retrieve" } },
|
|
1726
|
+
required: ["id"]
|
|
1636
1727
|
},
|
|
1637
1728
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
1638
1729
|
try {
|
|
1639
|
-
const
|
|
1730
|
+
const article_id = resolveId(args, "article_id");
|
|
1640
1731
|
const cached = await this.cache.get(`article:${article_id}`);
|
|
1641
1732
|
if (cached) {
|
|
1642
1733
|
return { content: [{ type: "text", text: JSON.stringify({ success: true, article: cached, from_cache: true }, null, 2) }] };
|
|
@@ -1662,8 +1753,7 @@ var ArticleToolHandler = class {
|
|
|
1662
1753
|
properties: {
|
|
1663
1754
|
search: { type: "string", description: "Search term to filter articles" },
|
|
1664
1755
|
status: { type: "string", description: "Filter by status" },
|
|
1665
|
-
|
|
1666
|
-
project_id: { type: "string", format: "uuid", description: "Filter by project (alias)" },
|
|
1756
|
+
project_id: { type: "string", format: "uuid", description: "Filter by project" },
|
|
1667
1757
|
maker: { type: "string", description: "Filter by maker" },
|
|
1668
1758
|
persona: { type: "string", description: "Filter by persona" },
|
|
1669
1759
|
author: { type: "string", description: "Filter by author" },
|
|
@@ -1677,7 +1767,12 @@ var ArticleToolHandler = class {
|
|
|
1677
1767
|
},
|
|
1678
1768
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
1679
1769
|
try {
|
|
1680
|
-
const
|
|
1770
|
+
const apiParams = { ...args };
|
|
1771
|
+
if (apiParams.project_id) {
|
|
1772
|
+
apiParams.projectId = apiParams.project_id;
|
|
1773
|
+
delete apiParams.project_id;
|
|
1774
|
+
}
|
|
1775
|
+
const result2 = await this.apiClient.listArticles(apiParams);
|
|
1681
1776
|
this.metrics.recordAPICall("list_articles", "success");
|
|
1682
1777
|
return {
|
|
1683
1778
|
content: [{
|
|
@@ -1686,7 +1781,17 @@ var ArticleToolHandler = class {
|
|
|
1686
1781
|
success: true,
|
|
1687
1782
|
total: result2.total,
|
|
1688
1783
|
count: result2.items.length,
|
|
1689
|
-
articles: result2.items.map((a) => ({
|
|
1784
|
+
articles: result2.items.map((a) => ({
|
|
1785
|
+
id: a.id,
|
|
1786
|
+
title: a.title,
|
|
1787
|
+
status: a.status,
|
|
1788
|
+
created_at: a.created_at,
|
|
1789
|
+
type: a.data?.input?.type,
|
|
1790
|
+
project_id: a.data?.input?.project_id,
|
|
1791
|
+
target_keyword: a.data?.input?.target_keyword,
|
|
1792
|
+
lang: a.data?.input?.lang,
|
|
1793
|
+
subject: a.data?.input?.subject
|
|
1794
|
+
})),
|
|
1690
1795
|
pagination: { skip: result2.skip, take: result2.take, has_more: result2.skip + result2.take < result2.total }
|
|
1691
1796
|
}, null, 2)
|
|
1692
1797
|
}]
|
|
@@ -1706,18 +1811,19 @@ var ArticleToolHandler = class {
|
|
|
1706
1811
|
inputSchema: {
|
|
1707
1812
|
type: "object",
|
|
1708
1813
|
properties: {
|
|
1709
|
-
|
|
1814
|
+
id: { type: "string", format: "uuid", description: "ID of the article to update" },
|
|
1710
1815
|
updates: {
|
|
1711
1816
|
type: "object",
|
|
1712
1817
|
description: "Fields to update (supports all create_article parameters)",
|
|
1713
1818
|
properties: this.buildArticleInputSchema()
|
|
1714
1819
|
}
|
|
1715
1820
|
},
|
|
1716
|
-
required: ["
|
|
1821
|
+
required: ["id", "updates"]
|
|
1717
1822
|
},
|
|
1718
1823
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
1719
1824
|
try {
|
|
1720
|
-
const
|
|
1825
|
+
const article_id = resolveId(args, "article_id");
|
|
1826
|
+
const { updates } = args;
|
|
1721
1827
|
await this.apiClient.updateArticle(article_id, updates);
|
|
1722
1828
|
await this.cache.delete(`article:${article_id}`);
|
|
1723
1829
|
this.metrics.recordAPICall("update_article", "success");
|
|
@@ -1739,14 +1845,15 @@ var ArticleToolHandler = class {
|
|
|
1739
1845
|
inputSchema: {
|
|
1740
1846
|
type: "object",
|
|
1741
1847
|
properties: {
|
|
1742
|
-
|
|
1848
|
+
id: { type: "string", format: "uuid", description: "ID of the article" },
|
|
1743
1849
|
format: { type: "string", enum: ["full", "html", "markdown", "summary"], description: "Output format", default: "full" }
|
|
1744
1850
|
},
|
|
1745
|
-
required: ["
|
|
1851
|
+
required: ["id"]
|
|
1746
1852
|
},
|
|
1747
1853
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
1748
1854
|
try {
|
|
1749
|
-
const
|
|
1855
|
+
const article_id = resolveId(args, "article_id");
|
|
1856
|
+
const { format = "full" } = args;
|
|
1750
1857
|
const cacheKey = `article:output:${article_id}`;
|
|
1751
1858
|
const cached = await this.cache.get(cacheKey);
|
|
1752
1859
|
const output = cached || await this.apiClient.getArticleOutput(article_id);
|
|
@@ -1754,19 +1861,30 @@ var ArticleToolHandler = class {
|
|
|
1754
1861
|
await this.cache.set(cacheKey, output, 600);
|
|
1755
1862
|
}
|
|
1756
1863
|
this.metrics.recordAPICall("get_article_output", "success");
|
|
1864
|
+
const rawOutput = output;
|
|
1865
|
+
const normalizedOutput = rawOutput?.data?.output ?? rawOutput?.data ?? rawOutput?.output ?? rawOutput;
|
|
1866
|
+
logger.debug("get_article_output raw response keys", { keys: Object.keys(rawOutput || {}), normalizedKeys: Object.keys(normalizedOutput || {}) });
|
|
1757
1867
|
let formattedOutput;
|
|
1758
1868
|
switch (format) {
|
|
1759
|
-
case "html":
|
|
1760
|
-
|
|
1869
|
+
case "html": {
|
|
1870
|
+
const html = normalizedOutput?.html_content ?? normalizedOutput?.content ?? null;
|
|
1871
|
+
const title = normalizedOutput?.title ?? null;
|
|
1872
|
+
formattedOutput = html || title ? { html, title } : { ...normalizedOutput, _note: "Fields not found at expected paths (html_content, title)" };
|
|
1761
1873
|
break;
|
|
1874
|
+
}
|
|
1762
1875
|
case "markdown":
|
|
1763
|
-
formattedOutput = { content:
|
|
1876
|
+
formattedOutput = { content: normalizedOutput?.content ?? normalizedOutput?.markdown ?? null, title: normalizedOutput?.title ?? null };
|
|
1764
1877
|
break;
|
|
1765
|
-
case "summary":
|
|
1766
|
-
|
|
1878
|
+
case "summary": {
|
|
1879
|
+
const title = normalizedOutput?.title ?? null;
|
|
1880
|
+
const excerpt = normalizedOutput?.excerpt ?? null;
|
|
1881
|
+
const word_count = normalizedOutput?.word_count ?? null;
|
|
1882
|
+
const seo_score = normalizedOutput?.seo_score ?? null;
|
|
1883
|
+
formattedOutput = title || excerpt ? { title, excerpt, word_count, seo_score } : { ...normalizedOutput, _note: "Fields not found at expected paths (title, excerpt)" };
|
|
1767
1884
|
break;
|
|
1885
|
+
}
|
|
1768
1886
|
default:
|
|
1769
|
-
formattedOutput =
|
|
1887
|
+
formattedOutput = normalizedOutput;
|
|
1770
1888
|
}
|
|
1771
1889
|
return { content: [{ type: "text", text: JSON.stringify({ success: true, article_id, format, output: formattedOutput, from_cache: !!cached }, null, 2) }] };
|
|
1772
1890
|
} catch (error) {
|
|
@@ -1784,15 +1902,16 @@ var ArticleToolHandler = class {
|
|
|
1784
1902
|
inputSchema: {
|
|
1785
1903
|
type: "object",
|
|
1786
1904
|
properties: {
|
|
1787
|
-
|
|
1905
|
+
id: { type: "string", format: "uuid", description: "ID of the article" },
|
|
1788
1906
|
output_id: { type: "string", format: "uuid", description: "ID of the output to update" },
|
|
1789
1907
|
updates: { type: "object", description: "Fields to update in the output" }
|
|
1790
1908
|
},
|
|
1791
|
-
required: ["
|
|
1909
|
+
required: ["id", "output_id", "updates"]
|
|
1792
1910
|
},
|
|
1793
1911
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
1794
1912
|
try {
|
|
1795
|
-
const
|
|
1913
|
+
const article_id = resolveId(args, "article_id");
|
|
1914
|
+
const { output_id, updates } = args;
|
|
1796
1915
|
const result2 = await this.apiClient.updateArticleOutput(article_id, output_id, updates);
|
|
1797
1916
|
await this.cache.delete(`article:output:${article_id}`);
|
|
1798
1917
|
this.metrics.recordAPICall("update_article_output", "success");
|
|
@@ -1947,18 +2066,18 @@ var ProjectToolHandler = class {
|
|
|
1947
2066
|
inputSchema: {
|
|
1948
2067
|
type: "object",
|
|
1949
2068
|
properties: {
|
|
1950
|
-
|
|
2069
|
+
id: {
|
|
1951
2070
|
type: "string",
|
|
1952
2071
|
format: "uuid",
|
|
1953
2072
|
description: "Project ID"
|
|
1954
2073
|
}
|
|
1955
2074
|
},
|
|
1956
|
-
required: ["
|
|
2075
|
+
required: ["id"]
|
|
1957
2076
|
},
|
|
1958
2077
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
1959
2078
|
try {
|
|
1960
|
-
const
|
|
1961
|
-
const cached = await this.cache.get(`project:${
|
|
2079
|
+
const id = resolveId(args, "project_id");
|
|
2080
|
+
const cached = await this.cache.get(`project:${id}`);
|
|
1962
2081
|
if (cached) {
|
|
1963
2082
|
return {
|
|
1964
2083
|
content: [
|
|
@@ -1973,8 +2092,8 @@ var ProjectToolHandler = class {
|
|
|
1973
2092
|
]
|
|
1974
2093
|
};
|
|
1975
2094
|
}
|
|
1976
|
-
const project = await this.apiClient.getProject(
|
|
1977
|
-
await this.cache.set(`project:${
|
|
2095
|
+
const project = await this.apiClient.getProject(id);
|
|
2096
|
+
await this.cache.set(`project:${id}`, project, 600);
|
|
1978
2097
|
this.metrics.recordAPICall("get_project", "success");
|
|
1979
2098
|
return {
|
|
1980
2099
|
content: [
|
|
@@ -2042,12 +2161,7 @@ var ProjectToolHandler = class {
|
|
|
2042
2161
|
success: true,
|
|
2043
2162
|
total: result2.total,
|
|
2044
2163
|
count: result2.items.length,
|
|
2045
|
-
projects: result2.items
|
|
2046
|
-
id: p.id,
|
|
2047
|
-
name: p.name,
|
|
2048
|
-
website_url: p.website_url,
|
|
2049
|
-
created_at: p.created_at
|
|
2050
|
-
}))
|
|
2164
|
+
projects: result2.items
|
|
2051
2165
|
}, null, 2)
|
|
2052
2166
|
}
|
|
2053
2167
|
]
|
|
@@ -2078,7 +2192,7 @@ var ProjectToolHandler = class {
|
|
|
2078
2192
|
inputSchema: {
|
|
2079
2193
|
type: "object",
|
|
2080
2194
|
properties: {
|
|
2081
|
-
|
|
2195
|
+
id: {
|
|
2082
2196
|
type: "string",
|
|
2083
2197
|
format: "uuid",
|
|
2084
2198
|
description: "Project ID"
|
|
@@ -2095,13 +2209,14 @@ var ProjectToolHandler = class {
|
|
|
2095
2209
|
}
|
|
2096
2210
|
}
|
|
2097
2211
|
},
|
|
2098
|
-
required: ["
|
|
2212
|
+
required: ["id", "updates"]
|
|
2099
2213
|
},
|
|
2100
2214
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
2101
2215
|
try {
|
|
2102
|
-
const
|
|
2103
|
-
|
|
2104
|
-
await this.
|
|
2216
|
+
const id = resolveId(args, "project_id");
|
|
2217
|
+
const { updates } = args;
|
|
2218
|
+
await this.apiClient.updateProject(id, updates);
|
|
2219
|
+
await this.cache.delete(`project:${id}`);
|
|
2105
2220
|
this.metrics.recordAPICall("update_project", "success");
|
|
2106
2221
|
return {
|
|
2107
2222
|
content: [
|
|
@@ -2110,7 +2225,7 @@ var ProjectToolHandler = class {
|
|
|
2110
2225
|
text: JSON.stringify({
|
|
2111
2226
|
success: true,
|
|
2112
2227
|
message: "Project updated successfully",
|
|
2113
|
-
project_id,
|
|
2228
|
+
project_id: id,
|
|
2114
2229
|
updated_fields: Object.keys(updates)
|
|
2115
2230
|
}, null, 2)
|
|
2116
2231
|
}
|
|
@@ -2142,7 +2257,7 @@ var ProjectToolHandler = class {
|
|
|
2142
2257
|
inputSchema: {
|
|
2143
2258
|
type: "object",
|
|
2144
2259
|
properties: {
|
|
2145
|
-
|
|
2260
|
+
id: {
|
|
2146
2261
|
type: "string",
|
|
2147
2262
|
format: "uuid",
|
|
2148
2263
|
description: "Project ID to delete"
|
|
@@ -2153,11 +2268,12 @@ var ProjectToolHandler = class {
|
|
|
2153
2268
|
const: true
|
|
2154
2269
|
}
|
|
2155
2270
|
},
|
|
2156
|
-
required: ["
|
|
2271
|
+
required: ["id", "confirm"]
|
|
2157
2272
|
},
|
|
2158
2273
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
2159
2274
|
try {
|
|
2160
|
-
const
|
|
2275
|
+
const id = resolveId(args, "project_id");
|
|
2276
|
+
const { confirm } = args;
|
|
2161
2277
|
if (!confirm) {
|
|
2162
2278
|
return {
|
|
2163
2279
|
content: [
|
|
@@ -2172,8 +2288,8 @@ var ProjectToolHandler = class {
|
|
|
2172
2288
|
isError: true
|
|
2173
2289
|
};
|
|
2174
2290
|
}
|
|
2175
|
-
await this.apiClient.deleteProject(
|
|
2176
|
-
await this.cache.delete(`project:${
|
|
2291
|
+
await this.apiClient.deleteProject(id);
|
|
2292
|
+
await this.cache.delete(`project:${id}`);
|
|
2177
2293
|
this.metrics.recordAPICall("delete_project", "success");
|
|
2178
2294
|
return {
|
|
2179
2295
|
content: [
|
|
@@ -2182,7 +2298,7 @@ var ProjectToolHandler = class {
|
|
|
2182
2298
|
text: JSON.stringify({
|
|
2183
2299
|
success: true,
|
|
2184
2300
|
message: "Project deleted successfully",
|
|
2185
|
-
project_id
|
|
2301
|
+
project_id: id
|
|
2186
2302
|
}, null, 2)
|
|
2187
2303
|
}
|
|
2188
2304
|
]
|
|
@@ -2229,33 +2345,104 @@ var PublishingToolHandler = class {
|
|
|
2229
2345
|
publishToWordPressTool() {
|
|
2230
2346
|
return {
|
|
2231
2347
|
name: "publish_to_wordpress",
|
|
2232
|
-
description: "Publish content to WordPress",
|
|
2348
|
+
description: "Publish content to WordPress. connection_id must reference a WordPress connection with sufficient permissions.",
|
|
2233
2349
|
inputSchema: {
|
|
2234
2350
|
type: "object",
|
|
2235
2351
|
properties: {
|
|
2236
2352
|
entity_id: { type: "string", format: "uuid", description: "ID of the article/content to publish" },
|
|
2237
2353
|
status: { type: "string", enum: ["draft", "publish", "future"], description: "Publishing status", default: "draft" },
|
|
2238
|
-
|
|
2354
|
+
date: { type: "string", format: "date-time", description: 'Publication date (ISO 8601). Required when status is "future".' },
|
|
2239
2355
|
category_id: { type: "number", description: "WordPress category ID" },
|
|
2240
|
-
author_id: { type: "number", description: "WordPress author ID" },
|
|
2241
|
-
connection_id: { type: "string", format: "uuid", description: "WordPress connection ID" }
|
|
2356
|
+
author_id: { type: "number", description: "WordPress author ID. CAUTION: If the WP connection user lacks edit_others_posts capability, setting this will cause publishing to fail with rest_cannot_edit_others. Omit unless the WP user has admin/editor role." },
|
|
2357
|
+
connection_id: { type: "string", format: "uuid", description: "WordPress connection ID (must have sufficient WP permissions)" },
|
|
2358
|
+
clear_author: { type: "boolean", description: 'Clear the stored publishwordpress_author from article config before publishing. Use this to prevent "rest_cannot_edit_others" errors.', default: false }
|
|
2242
2359
|
},
|
|
2243
|
-
required: ["entity_id"]
|
|
2360
|
+
required: ["entity_id", "connection_id"]
|
|
2244
2361
|
},
|
|
2245
2362
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
2246
2363
|
try {
|
|
2247
|
-
const
|
|
2364
|
+
const entity_id = resolveId(args, "entity_id");
|
|
2365
|
+
const { connection_id, status, date, category_id, author_id } = args;
|
|
2366
|
+
const clear_author = args.clear_author ?? false;
|
|
2367
|
+
const warnings = [];
|
|
2368
|
+
try {
|
|
2369
|
+
const article = await this.apiClient.getArticle(entity_id);
|
|
2370
|
+
const articleStatus = article.status || "unknown";
|
|
2371
|
+
if (articleStatus !== "completed" && articleStatus !== "success") {
|
|
2372
|
+
const statusMessages = {
|
|
2373
|
+
draft: "Article has not been generated yet.",
|
|
2374
|
+
pending: "Article generation is still pending.",
|
|
2375
|
+
processing: "Article is currently being generated.",
|
|
2376
|
+
failed: "Article generation failed previously.",
|
|
2377
|
+
error: "Article encountered an error during generation."
|
|
2378
|
+
};
|
|
2379
|
+
return {
|
|
2380
|
+
content: [{
|
|
2381
|
+
type: "text",
|
|
2382
|
+
text: JSON.stringify({
|
|
2383
|
+
error: true,
|
|
2384
|
+
message: statusMessages[articleStatus] || `Article status is "${articleStatus}" \u2014 content must be generated before publishing.`,
|
|
2385
|
+
article_status: articleStatus,
|
|
2386
|
+
entity_id,
|
|
2387
|
+
next_steps: [
|
|
2388
|
+
`Use 'generate_article' with id: ${entity_id} to generate content first`,
|
|
2389
|
+
`Use 'get_article' with id: ${entity_id} to check current status`
|
|
2390
|
+
]
|
|
2391
|
+
}, null, 2)
|
|
2392
|
+
}],
|
|
2393
|
+
isError: true
|
|
2394
|
+
};
|
|
2395
|
+
}
|
|
2396
|
+
const storedAuthor = article.data?.input?.publishwordpress_author;
|
|
2397
|
+
if (storedAuthor && !author_id) {
|
|
2398
|
+
if (clear_author) {
|
|
2399
|
+
try {
|
|
2400
|
+
await this.apiClient.updateArticle(entity_id, { publishwordpress_author: void 0 });
|
|
2401
|
+
logger.info("Cleared stored publishwordpress_author before publishing", { entity_id, cleared_author: storedAuthor });
|
|
2402
|
+
} catch (clearError) {
|
|
2403
|
+
logger.warn("Failed to clear publishwordpress_author", { error: clearError.message });
|
|
2404
|
+
warnings.push(`Could not clear stored publishwordpress_author (${storedAuthor}). Publishing may fail if the WP connection user lacks edit_others_posts.`);
|
|
2405
|
+
}
|
|
2406
|
+
} else {
|
|
2407
|
+
warnings.push(
|
|
2408
|
+
`Article has stored publishwordpress_author=${storedAuthor}. If the WP connection user lacks edit_others_posts capability, publishing will fail with "rest_cannot_edit_others". Use clear_author: true to clear it before publishing.`
|
|
2409
|
+
);
|
|
2410
|
+
}
|
|
2411
|
+
}
|
|
2412
|
+
} catch (fetchError) {
|
|
2413
|
+
logger.warn("Could not pre-validate article before publishing", { entity_id, error: fetchError.message });
|
|
2414
|
+
}
|
|
2415
|
+
const options = { connection_id };
|
|
2416
|
+
if (status) options.status = status;
|
|
2417
|
+
if (date) options.date = date;
|
|
2418
|
+
if (category_id) options.category_id = category_id;
|
|
2419
|
+
if (author_id) options.author_id = author_id;
|
|
2248
2420
|
const result2 = await this.apiClient.publishToWordPress(entity_id, options);
|
|
2249
2421
|
this.metrics.recordAPICall("publish_wordpress", result2.success ? "success" : "error");
|
|
2250
2422
|
if (result2.success) {
|
|
2251
|
-
|
|
2423
|
+
const response = {
|
|
2424
|
+
success: true,
|
|
2425
|
+
message: "Content published to WordPress successfully",
|
|
2426
|
+
entity_id,
|
|
2427
|
+
wordpress_url: result2.url,
|
|
2428
|
+
status: status || "draft"
|
|
2429
|
+
};
|
|
2430
|
+
if (warnings.length > 0) response.warnings = warnings;
|
|
2431
|
+
return { content: [{ type: "text", text: JSON.stringify(response, null, 2) }] };
|
|
2252
2432
|
} else {
|
|
2253
2433
|
throw new Error(result2.error || "Publishing failed");
|
|
2254
2434
|
}
|
|
2255
2435
|
} catch (error) {
|
|
2256
2436
|
logger.error("Failed to publish to WordPress", { error: error.message });
|
|
2257
2437
|
this.metrics.recordAPICall("publish_wordpress", "error");
|
|
2258
|
-
|
|
2438
|
+
const errorMsg = (error.message || "").toLowerCase();
|
|
2439
|
+
const hints = [];
|
|
2440
|
+
if (errorMsg.includes("rest_cannot_edit_others") || errorMsg.includes("403") || errorMsg.includes("cannot edit others")) {
|
|
2441
|
+
hints.push("This error is likely caused by a stored publishwordpress_author value. Try again with clear_author: true to clear it before publishing.");
|
|
2442
|
+
}
|
|
2443
|
+
const response = { error: true, message: error.message || "Failed to publish to WordPress" };
|
|
2444
|
+
if (hints.length > 0) response.hints = hints;
|
|
2445
|
+
return { content: [{ type: "text", text: JSON.stringify(response, null, 2) }], isError: true };
|
|
2259
2446
|
}
|
|
2260
2447
|
}, "handler")
|
|
2261
2448
|
};
|
|
@@ -2496,18 +2683,18 @@ var PersonaToolHandler = class {
|
|
|
2496
2683
|
inputSchema: {
|
|
2497
2684
|
type: "object",
|
|
2498
2685
|
properties: {
|
|
2499
|
-
|
|
2686
|
+
id: {
|
|
2500
2687
|
type: "string",
|
|
2501
2688
|
format: "uuid",
|
|
2502
2689
|
description: "Persona ID"
|
|
2503
2690
|
}
|
|
2504
2691
|
},
|
|
2505
|
-
required: ["
|
|
2692
|
+
required: ["id"]
|
|
2506
2693
|
},
|
|
2507
2694
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
2508
2695
|
try {
|
|
2509
|
-
const
|
|
2510
|
-
const cached = await this.cache.get(`persona:${
|
|
2696
|
+
const id = resolveId(args, "persona_id");
|
|
2697
|
+
const cached = await this.cache.get(`persona:${id}`);
|
|
2511
2698
|
if (cached) {
|
|
2512
2699
|
return {
|
|
2513
2700
|
content: [
|
|
@@ -2522,8 +2709,8 @@ var PersonaToolHandler = class {
|
|
|
2522
2709
|
]
|
|
2523
2710
|
};
|
|
2524
2711
|
}
|
|
2525
|
-
const persona = await this.apiClient.getPersona(
|
|
2526
|
-
await this.cache.set(`persona:${
|
|
2712
|
+
const persona = await this.apiClient.getPersona(id);
|
|
2713
|
+
await this.cache.set(`persona:${id}`, persona, 600);
|
|
2527
2714
|
this.metrics.recordAPICall("get_persona", "success");
|
|
2528
2715
|
return {
|
|
2529
2716
|
content: [
|
|
@@ -2628,7 +2815,7 @@ var PersonaToolHandler = class {
|
|
|
2628
2815
|
inputSchema: {
|
|
2629
2816
|
type: "object",
|
|
2630
2817
|
properties: {
|
|
2631
|
-
|
|
2818
|
+
id: {
|
|
2632
2819
|
type: "string",
|
|
2633
2820
|
format: "uuid",
|
|
2634
2821
|
description: "Persona ID"
|
|
@@ -2649,13 +2836,14 @@ var PersonaToolHandler = class {
|
|
|
2649
2836
|
}
|
|
2650
2837
|
}
|
|
2651
2838
|
},
|
|
2652
|
-
required: ["
|
|
2839
|
+
required: ["id", "updates"]
|
|
2653
2840
|
},
|
|
2654
2841
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
2655
2842
|
try {
|
|
2656
|
-
const
|
|
2657
|
-
|
|
2658
|
-
await this.
|
|
2843
|
+
const id = resolveId(args, "persona_id");
|
|
2844
|
+
const { updates } = args;
|
|
2845
|
+
await this.apiClient.updatePersona(id, updates);
|
|
2846
|
+
await this.cache.delete(`persona:${id}`);
|
|
2659
2847
|
this.metrics.recordAPICall("update_persona", "success");
|
|
2660
2848
|
return {
|
|
2661
2849
|
content: [
|
|
@@ -2664,7 +2852,7 @@ var PersonaToolHandler = class {
|
|
|
2664
2852
|
text: JSON.stringify({
|
|
2665
2853
|
success: true,
|
|
2666
2854
|
message: "Persona updated successfully",
|
|
2667
|
-
persona_id,
|
|
2855
|
+
persona_id: id,
|
|
2668
2856
|
updated_fields: Object.keys(updates)
|
|
2669
2857
|
}, null, 2)
|
|
2670
2858
|
}
|
|
@@ -2696,7 +2884,7 @@ var PersonaToolHandler = class {
|
|
|
2696
2884
|
inputSchema: {
|
|
2697
2885
|
type: "object",
|
|
2698
2886
|
properties: {
|
|
2699
|
-
|
|
2887
|
+
id: {
|
|
2700
2888
|
type: "string",
|
|
2701
2889
|
format: "uuid",
|
|
2702
2890
|
description: "Persona ID to delete"
|
|
@@ -2707,11 +2895,12 @@ var PersonaToolHandler = class {
|
|
|
2707
2895
|
const: true
|
|
2708
2896
|
}
|
|
2709
2897
|
},
|
|
2710
|
-
required: ["
|
|
2898
|
+
required: ["id", "confirm"]
|
|
2711
2899
|
},
|
|
2712
2900
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
2713
2901
|
try {
|
|
2714
|
-
const
|
|
2902
|
+
const id = resolveId(args, "persona_id");
|
|
2903
|
+
const { confirm } = args;
|
|
2715
2904
|
if (!confirm) {
|
|
2716
2905
|
return {
|
|
2717
2906
|
content: [
|
|
@@ -2726,8 +2915,8 @@ var PersonaToolHandler = class {
|
|
|
2726
2915
|
isError: true
|
|
2727
2916
|
};
|
|
2728
2917
|
}
|
|
2729
|
-
await this.apiClient.deletePersona(
|
|
2730
|
-
await this.cache.delete(`persona:${
|
|
2918
|
+
await this.apiClient.deletePersona(id);
|
|
2919
|
+
await this.cache.delete(`persona:${id}`);
|
|
2731
2920
|
this.metrics.recordAPICall("delete_persona", "success");
|
|
2732
2921
|
return {
|
|
2733
2922
|
content: [
|
|
@@ -2736,7 +2925,7 @@ var PersonaToolHandler = class {
|
|
|
2736
2925
|
text: JSON.stringify({
|
|
2737
2926
|
success: true,
|
|
2738
2927
|
message: "Persona deleted successfully",
|
|
2739
|
-
persona_id
|
|
2928
|
+
persona_id: id
|
|
2740
2929
|
}, null, 2)
|
|
2741
2930
|
}
|
|
2742
2931
|
]
|
|
@@ -2818,16 +3007,8 @@ var BulkOperationsToolHandler = class {
|
|
|
2818
3007
|
},
|
|
2819
3008
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
2820
3009
|
try {
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
logger.info("Converting articles from string to array");
|
|
2824
|
-
try {
|
|
2825
|
-
processedArgs.articles = JSON.parse(args.articles);
|
|
2826
|
-
} catch (error) {
|
|
2827
|
-
throw new Error("Invalid articles format: expected array or JSON string");
|
|
2828
|
-
}
|
|
2829
|
-
}
|
|
2830
|
-
const { articles, auto_generate = false } = processedArgs;
|
|
3010
|
+
const articles = resolveArray(args, "articles");
|
|
3011
|
+
const auto_generate = args.auto_generate ?? false;
|
|
2831
3012
|
logger.info("Validating and transforming article data types", { count: articles.length });
|
|
2832
3013
|
const validatedArticles = articles.map((article, index) => {
|
|
2833
3014
|
try {
|
|
@@ -2941,17 +3122,24 @@ var BulkOperationsToolHandler = class {
|
|
|
2941
3122
|
},
|
|
2942
3123
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
2943
3124
|
try {
|
|
2944
|
-
|
|
2945
|
-
if (typeof args.articles === "string") {
|
|
2946
|
-
logger.info("Converting articles from string to array (bulk cost estimate)");
|
|
2947
|
-
try {
|
|
2948
|
-
processedArgs.articles = JSON.parse(args.articles);
|
|
2949
|
-
} catch (error) {
|
|
2950
|
-
throw new Error("Invalid articles format: expected array or JSON string");
|
|
2951
|
-
}
|
|
2952
|
-
}
|
|
2953
|
-
const { articles } = processedArgs;
|
|
3125
|
+
const articles = resolveArray(args, "articles");
|
|
2954
3126
|
const result2 = await this.apiClient.calculateBulkCost(articles);
|
|
3127
|
+
logger.debug("bulk_estimate_cost raw API response keys", { keys: Object.keys(result2 || {}) });
|
|
3128
|
+
const breakdown = result2?.breakdown ?? result2?.items ?? result2?.estimates ?? [];
|
|
3129
|
+
let total;
|
|
3130
|
+
if (typeof result2?.total === "number" && !isNaN(result2.total)) {
|
|
3131
|
+
total = result2.total;
|
|
3132
|
+
} else if (typeof result2?.credits === "number" && !isNaN(result2.credits)) {
|
|
3133
|
+
total = result2.credits;
|
|
3134
|
+
} else if (typeof result2?.cost === "number" && !isNaN(result2.cost)) {
|
|
3135
|
+
total = result2.cost;
|
|
3136
|
+
} else if (Array.isArray(breakdown) && breakdown.length > 0) {
|
|
3137
|
+
total = breakdown.reduce((sum, item) => sum + (item?.credits ?? item?.cost ?? 0), 0);
|
|
3138
|
+
logger.info("bulk_estimate_cost: total derived from breakdown sum", { total });
|
|
3139
|
+
} else {
|
|
3140
|
+
total = 0;
|
|
3141
|
+
logger.warn("bulk_estimate_cost: could not extract total from API response, defaulting to 0", { resultKeys: Object.keys(result2 || {}) });
|
|
3142
|
+
}
|
|
2955
3143
|
this.metrics.recordAPICall("bulk_estimate_cost", "success");
|
|
2956
3144
|
return {
|
|
2957
3145
|
content: [
|
|
@@ -2960,16 +3148,15 @@ var BulkOperationsToolHandler = class {
|
|
|
2960
3148
|
text: JSON.stringify({
|
|
2961
3149
|
success: true,
|
|
2962
3150
|
total_cost: {
|
|
2963
|
-
credits:
|
|
2964
|
-
usd: (
|
|
2965
|
-
// Assuming 1 credit = $0.01
|
|
3151
|
+
credits: total,
|
|
3152
|
+
usd: (total * 0.01).toFixed(2)
|
|
2966
3153
|
},
|
|
2967
3154
|
article_count: articles.length,
|
|
2968
3155
|
average_cost_per_article: {
|
|
2969
|
-
credits: Math.round(
|
|
2970
|
-
usd: (
|
|
3156
|
+
credits: articles.length > 0 ? Math.round(total / articles.length) : 0,
|
|
3157
|
+
usd: articles.length > 0 ? (total / articles.length * 0.01).toFixed(2) : "0.00"
|
|
2971
3158
|
},
|
|
2972
|
-
breakdown
|
|
3159
|
+
breakdown
|
|
2973
3160
|
}, null, 2)
|
|
2974
3161
|
}
|
|
2975
3162
|
]
|
|
@@ -3093,18 +3280,18 @@ var ConnectionsToolHandler = class {
|
|
|
3093
3280
|
inputSchema: {
|
|
3094
3281
|
type: "object",
|
|
3095
3282
|
properties: {
|
|
3096
|
-
|
|
3283
|
+
id: {
|
|
3097
3284
|
type: "string",
|
|
3098
3285
|
format: "uuid",
|
|
3099
3286
|
description: "Connection ID"
|
|
3100
3287
|
}
|
|
3101
3288
|
},
|
|
3102
|
-
required: ["
|
|
3289
|
+
required: ["id"]
|
|
3103
3290
|
},
|
|
3104
3291
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
3105
3292
|
try {
|
|
3106
|
-
const
|
|
3107
|
-
const cached = await this.cache.get(`connection:${
|
|
3293
|
+
const id = resolveId(args, "connection_id");
|
|
3294
|
+
const cached = await this.cache.get(`connection:${id}`);
|
|
3108
3295
|
if (cached) {
|
|
3109
3296
|
return {
|
|
3110
3297
|
content: [
|
|
@@ -3119,8 +3306,8 @@ var ConnectionsToolHandler = class {
|
|
|
3119
3306
|
]
|
|
3120
3307
|
};
|
|
3121
3308
|
}
|
|
3122
|
-
const connection = await this.apiClient.getConnection(
|
|
3123
|
-
await this.cache.set(`connection:${
|
|
3309
|
+
const connection = await this.apiClient.getConnection(id);
|
|
3310
|
+
await this.cache.set(`connection:${id}`, connection, 600);
|
|
3124
3311
|
this.metrics.recordAPICall("get_connection", "success");
|
|
3125
3312
|
return {
|
|
3126
3313
|
content: [
|
|
@@ -3223,7 +3410,7 @@ var ConnectionsToolHandler = class {
|
|
|
3223
3410
|
inputSchema: {
|
|
3224
3411
|
type: "object",
|
|
3225
3412
|
properties: {
|
|
3226
|
-
|
|
3413
|
+
id: {
|
|
3227
3414
|
type: "string",
|
|
3228
3415
|
format: "uuid",
|
|
3229
3416
|
description: "Connection ID"
|
|
@@ -3236,13 +3423,14 @@ var ConnectionsToolHandler = class {
|
|
|
3236
3423
|
}
|
|
3237
3424
|
}
|
|
3238
3425
|
},
|
|
3239
|
-
required: ["
|
|
3426
|
+
required: ["id", "updates"]
|
|
3240
3427
|
},
|
|
3241
3428
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
3242
3429
|
try {
|
|
3243
|
-
const
|
|
3244
|
-
|
|
3245
|
-
await this.
|
|
3430
|
+
const id = resolveId(args, "connection_id");
|
|
3431
|
+
const { updates } = args;
|
|
3432
|
+
await this.apiClient.updateConnection(id, updates);
|
|
3433
|
+
await this.cache.delete(`connection:${id}`);
|
|
3246
3434
|
this.metrics.recordAPICall("update_connection", "success");
|
|
3247
3435
|
return {
|
|
3248
3436
|
content: [
|
|
@@ -3251,7 +3439,7 @@ var ConnectionsToolHandler = class {
|
|
|
3251
3439
|
text: JSON.stringify({
|
|
3252
3440
|
success: true,
|
|
3253
3441
|
message: "Connection updated successfully",
|
|
3254
|
-
connection_id
|
|
3442
|
+
connection_id: id
|
|
3255
3443
|
}, null, 2)
|
|
3256
3444
|
}
|
|
3257
3445
|
]
|
|
@@ -3282,7 +3470,7 @@ var ConnectionsToolHandler = class {
|
|
|
3282
3470
|
inputSchema: {
|
|
3283
3471
|
type: "object",
|
|
3284
3472
|
properties: {
|
|
3285
|
-
|
|
3473
|
+
id: {
|
|
3286
3474
|
type: "string",
|
|
3287
3475
|
format: "uuid",
|
|
3288
3476
|
description: "Connection ID to delete"
|
|
@@ -3293,11 +3481,12 @@ var ConnectionsToolHandler = class {
|
|
|
3293
3481
|
const: true
|
|
3294
3482
|
}
|
|
3295
3483
|
},
|
|
3296
|
-
required: ["
|
|
3484
|
+
required: ["id", "confirm"]
|
|
3297
3485
|
},
|
|
3298
3486
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
3299
3487
|
try {
|
|
3300
|
-
const
|
|
3488
|
+
const id = resolveId(args, "connection_id");
|
|
3489
|
+
const { confirm } = args;
|
|
3301
3490
|
if (!confirm) {
|
|
3302
3491
|
return {
|
|
3303
3492
|
content: [
|
|
@@ -3312,8 +3501,8 @@ var ConnectionsToolHandler = class {
|
|
|
3312
3501
|
isError: true
|
|
3313
3502
|
};
|
|
3314
3503
|
}
|
|
3315
|
-
await this.apiClient.deleteConnection(
|
|
3316
|
-
await this.cache.delete(`connection:${
|
|
3504
|
+
await this.apiClient.deleteConnection(id);
|
|
3505
|
+
await this.cache.delete(`connection:${id}`);
|
|
3317
3506
|
this.metrics.recordAPICall("delete_connection", "success");
|
|
3318
3507
|
return {
|
|
3319
3508
|
content: [
|
|
@@ -3322,7 +3511,7 @@ var ConnectionsToolHandler = class {
|
|
|
3322
3511
|
text: JSON.stringify({
|
|
3323
3512
|
success: true,
|
|
3324
3513
|
message: "Connection deleted successfully",
|
|
3325
|
-
connection_id
|
|
3514
|
+
connection_id: id
|
|
3326
3515
|
}, null, 2)
|
|
3327
3516
|
}
|
|
3328
3517
|
]
|
|
@@ -3592,7 +3781,7 @@ var CategoryPagesToolHandler = class {
|
|
|
3592
3781
|
country: { type: "string", enum: [...COUNTRY_ENUM2], description: "Target country for localization" },
|
|
3593
3782
|
project_id: { type: "string", format: "uuid", description: "Project UUID" },
|
|
3594
3783
|
persona_id: { type: "string", format: "uuid", description: "Persona UUID" },
|
|
3595
|
-
apply_project_brief_config: { type: "boolean", description: "Apply project configuration", default: false },
|
|
3784
|
+
apply_project_brief_config: { type: "boolean", description: "Apply project configuration. When true with a project_id, lang/country will be inherited from the project if not explicitly provided.", default: false },
|
|
3596
3785
|
use_faq: { type: "boolean", description: "Generate FAQ section", default: false },
|
|
3597
3786
|
use_toc: { type: "boolean", description: "Generate table of contents", default: false },
|
|
3598
3787
|
use_image: { type: "boolean", description: "Generate featured image", default: false },
|
|
@@ -3605,7 +3794,7 @@ var CategoryPagesToolHandler = class {
|
|
|
3605
3794
|
publishwordpress_date: { type: "string", description: "Publication date (ISO 8601 or WordPress format)" },
|
|
3606
3795
|
publishwordpress_status: { type: "string", enum: ["draft", "publish", "future"], description: "WordPress post status" },
|
|
3607
3796
|
publishwordpress_category: { type: "number", description: "WordPress category ID" },
|
|
3608
|
-
publishwordpress_author: { type: "number", description: "WordPress author ID" },
|
|
3797
|
+
publishwordpress_author: { type: "number", description: "WordPress author ID. CAUTION: If the WP connection user lacks edit_others_posts capability, setting this will cause publishing to fail with rest_cannot_edit_others. Omit unless the WP user has admin/editor role." },
|
|
3609
3798
|
publishwordpress_connection: { type: "string", format: "uuid", description: "WordPress connection UUID" }
|
|
3610
3799
|
},
|
|
3611
3800
|
required: ["name", "subject"]
|
|
@@ -3613,9 +3802,21 @@ var CategoryPagesToolHandler = class {
|
|
|
3613
3802
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
3614
3803
|
try {
|
|
3615
3804
|
const validated = CreateCategoryPageSchema.parse(args);
|
|
3805
|
+
if (validated.apply_project_brief_config && validated.project_id && (!validated.lang || !validated.country)) {
|
|
3806
|
+
try {
|
|
3807
|
+
const project = await this.apiClient.getProject(validated.project_id);
|
|
3808
|
+
if (!validated.lang && project.default_lang) {
|
|
3809
|
+
validated.lang = project.default_lang;
|
|
3810
|
+
}
|
|
3811
|
+
if (!validated.country && project.default_country) {
|
|
3812
|
+
validated.country = project.default_country;
|
|
3813
|
+
}
|
|
3814
|
+
} catch (e) {
|
|
3815
|
+
logger.warn("Could not fetch project for lang/country defaults", { error: e.message });
|
|
3816
|
+
}
|
|
3817
|
+
}
|
|
3616
3818
|
const input = this.buildApiInput(validated);
|
|
3617
3819
|
const categoryPage = await this.apiClient.createCategoryPage(input);
|
|
3618
|
-
await this.cache.set(`category_page:${categoryPage.id}`, categoryPage, 300);
|
|
3619
3820
|
this.metrics.recordAPICall("create_category_page", "success");
|
|
3620
3821
|
const displayName = categoryPage.name || validated.name || args.name || "Unnamed";
|
|
3621
3822
|
return {
|
|
@@ -3636,7 +3837,7 @@ var CategoryPagesToolHandler = class {
|
|
|
3636
3837
|
inputSchema: { type: "object", properties: { id: { type: "string", format: "uuid", description: "ID of the category page" } }, required: ["id"] },
|
|
3637
3838
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
3638
3839
|
try {
|
|
3639
|
-
const
|
|
3840
|
+
const id = resolveId(args);
|
|
3640
3841
|
const cached = await this.cache.get(`category_page:${id}`);
|
|
3641
3842
|
if (cached) {
|
|
3642
3843
|
return { content: [{ type: "text", text: JSON.stringify({ success: true, category_page: cached, from_cache: true }, null, 2) }] };
|
|
@@ -3696,7 +3897,8 @@ var CategoryPagesToolHandler = class {
|
|
|
3696
3897
|
},
|
|
3697
3898
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
3698
3899
|
try {
|
|
3699
|
-
const
|
|
3900
|
+
const id = resolveId(args);
|
|
3901
|
+
const { updates } = args;
|
|
3700
3902
|
await this.apiClient.updateCategoryPage(id, updates);
|
|
3701
3903
|
await this.cache.delete(`category_page:${id}`);
|
|
3702
3904
|
this.metrics.recordAPICall("update_category_page", "success");
|
|
@@ -3724,7 +3926,8 @@ var CategoryPagesToolHandler = class {
|
|
|
3724
3926
|
},
|
|
3725
3927
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
3726
3928
|
try {
|
|
3727
|
-
const
|
|
3929
|
+
const id = resolveId(args);
|
|
3930
|
+
const { wait_for_completion = true, max_wait_time = 300 } = args;
|
|
3728
3931
|
await this.apiClient.runCategoryPageGeneration(id);
|
|
3729
3932
|
if (!wait_for_completion) {
|
|
3730
3933
|
return { content: [{ type: "text", text: JSON.stringify({ success: true, message: "Category page generation started", category_page_id: id }, null, 2) }] };
|
|
@@ -3760,7 +3963,7 @@ var CategoryPagesToolHandler = class {
|
|
|
3760
3963
|
inputSchema: { type: "object", properties: { id: { type: "string", format: "uuid", description: "ID of the category page" } }, required: ["id"] },
|
|
3761
3964
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
3762
3965
|
try {
|
|
3763
|
-
const
|
|
3966
|
+
const id = resolveId(args);
|
|
3764
3967
|
const cacheKey = `category_page:output:${id}`;
|
|
3765
3968
|
const cached = await this.cache.get(cacheKey);
|
|
3766
3969
|
const output = cached || await this.apiClient.getCategoryPageOutput(id);
|
|
@@ -3781,10 +3984,19 @@ var CategoryPagesToolHandler = class {
|
|
|
3781
3984
|
return {
|
|
3782
3985
|
name: "estimate_category_page_cost",
|
|
3783
3986
|
description: "Estimate the cost of generating a category page",
|
|
3784
|
-
inputSchema: {
|
|
3987
|
+
inputSchema: {
|
|
3988
|
+
type: "object",
|
|
3989
|
+
properties: {
|
|
3990
|
+
subject: { type: "string", description: "Category page subject", minLength: 1 },
|
|
3991
|
+
length: { oneOf: [{ type: "number", maximum: 5e3 }, { type: "string", const: "auto" }], default: "auto" },
|
|
3992
|
+
use_image: { type: "boolean", default: false }
|
|
3993
|
+
},
|
|
3994
|
+
required: ["subject"]
|
|
3995
|
+
},
|
|
3785
3996
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
3786
3997
|
try {
|
|
3787
|
-
const
|
|
3998
|
+
const costInput = args.data || args;
|
|
3999
|
+
const cost = await this.apiClient.calculateCategoryPageCost(costInput);
|
|
3788
4000
|
this.metrics.recordAPICall("estimate_category_page_cost", "success");
|
|
3789
4001
|
return { content: [{ type: "text", text: JSON.stringify({ success: true, cost_estimate: cost }, null, 2) }] };
|
|
3790
4002
|
} catch (error) {
|
|
@@ -3802,7 +4014,7 @@ var CategoryPagesToolHandler = class {
|
|
|
3802
4014
|
inputSchema: { type: "object", properties: { items: { type: "array", items: { type: "object" }, description: "Array of category page configurations" } }, required: ["items"] },
|
|
3803
4015
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
3804
4016
|
try {
|
|
3805
|
-
const
|
|
4017
|
+
const items = resolveArray(args, "items");
|
|
3806
4018
|
const result2 = await this.apiClient.createBulkCategoryPages(items);
|
|
3807
4019
|
this.metrics.recordAPICall("bulk_create_category_pages", "success");
|
|
3808
4020
|
return { content: [{ type: "text", text: JSON.stringify({ success: true, message: `Bulk created ${items.length} category pages`, result: result2 }, null, 2) }] };
|
|
@@ -3906,7 +4118,7 @@ var ProductPagesToolHandler = class {
|
|
|
3906
4118
|
country: { type: "string", enum: [...COUNTRY_ENUM3], description: "Target country for localization" },
|
|
3907
4119
|
project_id: { type: "string", format: "uuid", description: "Project UUID" },
|
|
3908
4120
|
persona_id: { type: "string", format: "uuid", description: "Persona UUID" },
|
|
3909
|
-
apply_project_brief_config: { type: "boolean", description: "Apply project configuration", default: false },
|
|
4121
|
+
apply_project_brief_config: { type: "boolean", description: "Apply project configuration. When true with a project_id, lang/country will be inherited from the project if not explicitly provided.", default: false },
|
|
3910
4122
|
use_faq: { type: "boolean", description: "Generate FAQ section", default: false },
|
|
3911
4123
|
use_toc: { type: "boolean", description: "Generate table of contents", default: false },
|
|
3912
4124
|
use_image: { type: "boolean", description: "Generate featured image", default: false },
|
|
@@ -3919,7 +4131,7 @@ var ProductPagesToolHandler = class {
|
|
|
3919
4131
|
publishwordpress_date: { type: "string", description: "Publication date (ISO 8601 or WordPress format)" },
|
|
3920
4132
|
publishwordpress_status: { type: "string", enum: ["draft", "publish", "future"], description: "WordPress post status" },
|
|
3921
4133
|
publishwordpress_category: { type: "number", description: "WordPress category ID" },
|
|
3922
|
-
publishwordpress_author: { type: "number", description: "WordPress author ID" },
|
|
4134
|
+
publishwordpress_author: { type: "number", description: "WordPress author ID. CAUTION: If the WP connection user lacks edit_others_posts capability, setting this will cause publishing to fail with rest_cannot_edit_others. Omit unless the WP user has admin/editor role." },
|
|
3923
4135
|
publishwordpress_connection: { type: "string", format: "uuid", description: "WordPress connection UUID" }
|
|
3924
4136
|
},
|
|
3925
4137
|
required: ["name", "subject"]
|
|
@@ -3927,9 +4139,21 @@ var ProductPagesToolHandler = class {
|
|
|
3927
4139
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
3928
4140
|
try {
|
|
3929
4141
|
const validated = CreateProductPageSchema.parse(args);
|
|
4142
|
+
if (validated.apply_project_brief_config && validated.project_id && (!validated.lang || !validated.country)) {
|
|
4143
|
+
try {
|
|
4144
|
+
const project = await this.apiClient.getProject(validated.project_id);
|
|
4145
|
+
if (!validated.lang && project.default_lang) {
|
|
4146
|
+
validated.lang = project.default_lang;
|
|
4147
|
+
}
|
|
4148
|
+
if (!validated.country && project.default_country) {
|
|
4149
|
+
validated.country = project.default_country;
|
|
4150
|
+
}
|
|
4151
|
+
} catch (e) {
|
|
4152
|
+
logger.warn("Could not fetch project for lang/country defaults", { error: e.message });
|
|
4153
|
+
}
|
|
4154
|
+
}
|
|
3930
4155
|
const input = this.buildApiInput(validated);
|
|
3931
4156
|
const productPage = await this.apiClient.createProductPage(input);
|
|
3932
|
-
await this.cache.set(`product_page:${productPage.id}`, productPage, 300);
|
|
3933
4157
|
this.metrics.recordAPICall("create_product_page", "success");
|
|
3934
4158
|
const displayName = productPage.name || validated.name || args.name || "Unnamed";
|
|
3935
4159
|
return { content: [{ type: "text", text: JSON.stringify({ success: true, product_page_id: productPage.id, name: displayName, message: `Product page "${displayName}" created successfully`, next_steps: [`Use 'generate_product_page' with id: ${productPage.id}`, `Use 'get_product_page' with id: ${productPage.id}`] }, null, 2) }] };
|
|
@@ -3948,7 +4172,7 @@ var ProductPagesToolHandler = class {
|
|
|
3948
4172
|
inputSchema: { type: "object", properties: { id: { type: "string", format: "uuid", description: "ID of the product page" } }, required: ["id"] },
|
|
3949
4173
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
3950
4174
|
try {
|
|
3951
|
-
const
|
|
4175
|
+
const id = resolveId(args);
|
|
3952
4176
|
const cached = await this.cache.get(`product_page:${id}`);
|
|
3953
4177
|
if (cached) {
|
|
3954
4178
|
return { content: [{ type: "text", text: JSON.stringify({ success: true, product_page: cached, from_cache: true }, null, 2) }] };
|
|
@@ -3999,7 +4223,8 @@ var ProductPagesToolHandler = class {
|
|
|
3999
4223
|
inputSchema: { type: "object", properties: { id: { type: "string", format: "uuid", description: "ID of the product page to update" }, updates: { type: "object", description: "Fields to update" } }, required: ["id", "updates"] },
|
|
4000
4224
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
4001
4225
|
try {
|
|
4002
|
-
const
|
|
4226
|
+
const id = resolveId(args);
|
|
4227
|
+
const { updates } = args;
|
|
4003
4228
|
await this.apiClient.updateProductPage(id, updates);
|
|
4004
4229
|
await this.cache.delete(`product_page:${id}`);
|
|
4005
4230
|
this.metrics.recordAPICall("update_product_page", "success");
|
|
@@ -4019,7 +4244,8 @@ var ProductPagesToolHandler = class {
|
|
|
4019
4244
|
inputSchema: { type: "object", properties: { id: { type: "string", format: "uuid" }, wait_for_completion: { type: "boolean", default: true }, max_wait_time: { type: "number", default: 300, maximum: 600 } }, required: ["id"] },
|
|
4020
4245
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
4021
4246
|
try {
|
|
4022
|
-
const
|
|
4247
|
+
const id = resolveId(args);
|
|
4248
|
+
const { wait_for_completion = true, max_wait_time = 300 } = args;
|
|
4023
4249
|
await this.apiClient.runProductPageGeneration(id);
|
|
4024
4250
|
if (!wait_for_completion) {
|
|
4025
4251
|
return { content: [{ type: "text", text: JSON.stringify({ success: true, message: "Product page generation started", product_page_id: id }, null, 2) }] };
|
|
@@ -4055,7 +4281,7 @@ var ProductPagesToolHandler = class {
|
|
|
4055
4281
|
inputSchema: { type: "object", properties: { id: { type: "string", format: "uuid" } }, required: ["id"] },
|
|
4056
4282
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
4057
4283
|
try {
|
|
4058
|
-
const
|
|
4284
|
+
const id = resolveId(args);
|
|
4059
4285
|
const cacheKey = `product_page:output:${id}`;
|
|
4060
4286
|
const cached = await this.cache.get(cacheKey);
|
|
4061
4287
|
const output = cached || await this.apiClient.getProductPageOutput(id);
|
|
@@ -4076,10 +4302,19 @@ var ProductPagesToolHandler = class {
|
|
|
4076
4302
|
return {
|
|
4077
4303
|
name: "estimate_product_page_cost",
|
|
4078
4304
|
description: "Estimate the cost of generating a product page",
|
|
4079
|
-
inputSchema: {
|
|
4305
|
+
inputSchema: {
|
|
4306
|
+
type: "object",
|
|
4307
|
+
properties: {
|
|
4308
|
+
subject: { type: "string", description: "Product page subject", minLength: 1 },
|
|
4309
|
+
length: { oneOf: [{ type: "number", maximum: 5e3 }, { type: "string", const: "auto" }], default: "auto" },
|
|
4310
|
+
use_image: { type: "boolean", default: false }
|
|
4311
|
+
},
|
|
4312
|
+
required: ["subject"]
|
|
4313
|
+
},
|
|
4080
4314
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
4081
4315
|
try {
|
|
4082
|
-
const
|
|
4316
|
+
const costInput = args.data || args;
|
|
4317
|
+
const cost = await this.apiClient.calculateProductPageCost(costInput);
|
|
4083
4318
|
this.metrics.recordAPICall("estimate_product_page_cost", "success");
|
|
4084
4319
|
return { content: [{ type: "text", text: JSON.stringify({ success: true, cost_estimate: cost }, null, 2) }] };
|
|
4085
4320
|
} catch (error) {
|
|
@@ -4097,7 +4332,7 @@ var ProductPagesToolHandler = class {
|
|
|
4097
4332
|
inputSchema: { type: "object", properties: { items: { type: "array", items: { type: "object" }, description: "Array of product page configurations" } }, required: ["items"] },
|
|
4098
4333
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
4099
4334
|
try {
|
|
4100
|
-
const
|
|
4335
|
+
const items = resolveArray(args, "items");
|
|
4101
4336
|
const result2 = await this.apiClient.createBulkProductPages(items);
|
|
4102
4337
|
this.metrics.recordAPICall("bulk_create_product_pages", "success");
|
|
4103
4338
|
return { content: [{ type: "text", text: JSON.stringify({ success: true, message: `Bulk created ${items.length} product pages`, result: result2 }, null, 2) }] };
|
|
@@ -4218,7 +4453,7 @@ var DiscoverToolHandler = class {
|
|
|
4218
4453
|
keywords_secondary: { type: "string", description: "Secondary keywords" },
|
|
4219
4454
|
project_id: { type: "string", format: "uuid", description: "Project UUID" },
|
|
4220
4455
|
persona_id: { type: "string", format: "uuid", description: "Persona UUID" },
|
|
4221
|
-
apply_project_brief_config: { type: "boolean", description: "Apply project brief configuration settings. When true, inherits all feature flags and settings from the project brief (use_faq, use_toc, use_inline_images, internal links, etc.). Recommended for consistency.", default: false },
|
|
4456
|
+
apply_project_brief_config: { type: "boolean", description: "Apply project brief configuration settings. When true, inherits all feature flags and settings from the project brief (use_faq, use_toc, use_inline_images, internal links, etc.). When true with a project_id, lang/country will be inherited from the project if not explicitly provided. Recommended for consistency.", default: false },
|
|
4222
4457
|
lang: { type: "string", enum: ["fr", "en"], description: "Language code" },
|
|
4223
4458
|
country: { type: "string", enum: ["fr", "be", "ch", "ca", "us", "gb"], description: "Country code" },
|
|
4224
4459
|
length: { description: 'Number (max 2000) or "auto"' },
|
|
@@ -4260,7 +4495,7 @@ var DiscoverToolHandler = class {
|
|
|
4260
4495
|
publishwordpress_date: { type: "string", description: "WordPress publish date" },
|
|
4261
4496
|
publishwordpress_status: { type: "string", enum: ["draft", "publish", "future"], description: "WordPress post status" },
|
|
4262
4497
|
publishwordpress_category: { type: "number", description: "WordPress category ID" },
|
|
4263
|
-
publishwordpress_author: { type: "number", description: "WordPress author ID" },
|
|
4498
|
+
publishwordpress_author: { type: "number", description: "WordPress author ID. CAUTION: If the WP connection user lacks edit_others_posts capability, setting this will cause publishing to fail with rest_cannot_edit_others. Omit unless the WP user has admin/editor role." },
|
|
4264
4499
|
publishwordpress_connection: { type: "string", description: "WordPress connection ID" },
|
|
4265
4500
|
// Additional features
|
|
4266
4501
|
use_infotable: { type: "boolean", description: "Add info table" },
|
|
@@ -4285,6 +4520,19 @@ var DiscoverToolHandler = class {
|
|
|
4285
4520
|
apply_project_brief_config_raw_type: typeof args.apply_project_brief_config
|
|
4286
4521
|
});
|
|
4287
4522
|
const validated = DiscoverContentSchema.parse(args);
|
|
4523
|
+
if (validated.apply_project_brief_config && validated.project_id && (!validated.lang || !validated.country)) {
|
|
4524
|
+
try {
|
|
4525
|
+
const project = await this.apiClient.getProject(validated.project_id);
|
|
4526
|
+
if (!validated.lang && project.default_lang) {
|
|
4527
|
+
validated.lang = project.default_lang;
|
|
4528
|
+
}
|
|
4529
|
+
if (!validated.country && project.default_country) {
|
|
4530
|
+
validated.country = project.default_country;
|
|
4531
|
+
}
|
|
4532
|
+
} catch (e) {
|
|
4533
|
+
logger.warn("Could not fetch project for lang/country defaults", { error: e.message });
|
|
4534
|
+
}
|
|
4535
|
+
}
|
|
4288
4536
|
logger.info("discover_content VALIDATED (after boolField transform)", {
|
|
4289
4537
|
apply_project_brief_config: validated.apply_project_brief_config,
|
|
4290
4538
|
apply_project_brief_config_type: typeof validated.apply_project_brief_config,
|
|
@@ -4304,7 +4552,6 @@ var DiscoverToolHandler = class {
|
|
|
4304
4552
|
apply_project_brief_config_value: cleanedInput.apply_project_brief_config
|
|
4305
4553
|
});
|
|
4306
4554
|
const discovery = await this.apiClient.discoverArticles(cleanedInput);
|
|
4307
|
-
await this.cache.set(`discover:${discovery.id}`, discovery, 300);
|
|
4308
4555
|
this.metrics.recordAPICall("discover_content", "success");
|
|
4309
4556
|
return {
|
|
4310
4557
|
content: [{
|
|
@@ -4335,7 +4582,7 @@ var DiscoverToolHandler = class {
|
|
|
4335
4582
|
inputSchema: { type: "object", properties: { id: { type: "string", format: "uuid" } }, required: ["id"] },
|
|
4336
4583
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
4337
4584
|
try {
|
|
4338
|
-
const
|
|
4585
|
+
const id = resolveId(args);
|
|
4339
4586
|
const cached = await this.cache.get(`discover:${id}`);
|
|
4340
4587
|
if (cached) {
|
|
4341
4588
|
return { content: [{ type: "text", text: JSON.stringify({ success: true, discovery: cached, from_cache: true }, null, 2) }] };
|
|
@@ -4386,7 +4633,8 @@ var DiscoverToolHandler = class {
|
|
|
4386
4633
|
inputSchema: { type: "object", properties: { id: { type: "string", format: "uuid" }, updates: { type: "object", description: "Fields to update" } }, required: ["id", "updates"] },
|
|
4387
4634
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
4388
4635
|
try {
|
|
4389
|
-
const
|
|
4636
|
+
const id = resolveId(args);
|
|
4637
|
+
const { updates } = args;
|
|
4390
4638
|
await this.apiClient.updateDiscoverArticle(id, updates);
|
|
4391
4639
|
await this.cache.delete(`discover:${id}`);
|
|
4392
4640
|
this.metrics.recordAPICall("update_discover_article", "success");
|
|
@@ -4406,7 +4654,7 @@ var DiscoverToolHandler = class {
|
|
|
4406
4654
|
inputSchema: { type: "object", properties: { id: { type: "string", format: "uuid" } }, required: ["id"] },
|
|
4407
4655
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
4408
4656
|
try {
|
|
4409
|
-
const
|
|
4657
|
+
const id = resolveId(args);
|
|
4410
4658
|
await this.apiClient.runDiscovery(id);
|
|
4411
4659
|
await this.cache.delete(`discover:${id}`);
|
|
4412
4660
|
this.metrics.recordAPICall("run_discovery", "success");
|
|
@@ -4426,7 +4674,7 @@ var DiscoverToolHandler = class {
|
|
|
4426
4674
|
inputSchema: { type: "object", properties: { id: { type: "string", format: "uuid" } }, required: ["id"] },
|
|
4427
4675
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
4428
4676
|
try {
|
|
4429
|
-
const
|
|
4677
|
+
const id = resolveId(args);
|
|
4430
4678
|
const cacheKey = `discover:output:${id}`;
|
|
4431
4679
|
const cached = await this.cache.get(cacheKey);
|
|
4432
4680
|
const output = cached || await this.apiClient.getDiscoverArticleOutput(id);
|
|
@@ -4447,10 +4695,19 @@ var DiscoverToolHandler = class {
|
|
|
4447
4695
|
return {
|
|
4448
4696
|
name: "estimate_discover_cost",
|
|
4449
4697
|
description: "Estimate the cost of a discover article",
|
|
4450
|
-
inputSchema: {
|
|
4698
|
+
inputSchema: {
|
|
4699
|
+
type: "object",
|
|
4700
|
+
properties: {
|
|
4701
|
+
subject: { type: "string", description: "Discover article subject", minLength: 1 },
|
|
4702
|
+
length: { oneOf: [{ type: "number", maximum: 2e3 }, { type: "string", const: "auto" }], default: "auto" },
|
|
4703
|
+
use_image: { type: "boolean", default: false }
|
|
4704
|
+
},
|
|
4705
|
+
required: ["subject"]
|
|
4706
|
+
},
|
|
4451
4707
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
4452
4708
|
try {
|
|
4453
|
-
const
|
|
4709
|
+
const costInput = args.data || args;
|
|
4710
|
+
const cost = await this.apiClient.calculateDiscoverCost(costInput);
|
|
4454
4711
|
this.metrics.recordAPICall("estimate_discover_cost", "success");
|
|
4455
4712
|
return { content: [{ type: "text", text: JSON.stringify({ success: true, cost_estimate: cost }, null, 2) }] };
|
|
4456
4713
|
} catch (error) {
|
|
@@ -4468,7 +4725,7 @@ var DiscoverToolHandler = class {
|
|
|
4468
4725
|
inputSchema: { type: "object", properties: { items: { type: "array", items: { type: "object" }, description: "Array of discover article configurations" } }, required: ["items"] },
|
|
4469
4726
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
4470
4727
|
try {
|
|
4471
|
-
const
|
|
4728
|
+
const items = resolveArray(args, "items");
|
|
4472
4729
|
const result2 = await this.apiClient.createBulkDiscoverArticles(items);
|
|
4473
4730
|
this.metrics.recordAPICall("bulk_create_discover_articles", "success");
|
|
4474
4731
|
return { content: [{ type: "text", text: JSON.stringify({ success: true, message: `Bulk created ${items.length} discover articles`, result: result2 }, null, 2) }] };
|
|
@@ -4561,8 +4818,10 @@ var RSSToolHandler = class {
|
|
|
4561
4818
|
} catch (error) {
|
|
4562
4819
|
logger.error("Failed to create feed", { error: error.message });
|
|
4563
4820
|
this.metrics.recordAPICall("create_feed", "error");
|
|
4821
|
+
const errorMessage = error.message || "Failed to create feed";
|
|
4822
|
+
const guidance = "Please verify the feed URL is a valid RSS/Atom feed and is accessible. If the URL is correct, this may be a temporary Wisewand service issue \u2014 try again later.";
|
|
4564
4823
|
return {
|
|
4565
|
-
content: [{ type: "text", text: JSON.stringify({ error: true, message:
|
|
4824
|
+
content: [{ type: "text", text: JSON.stringify({ error: true, message: errorMessage, guidance, details: error.issues || void 0 }, null, 2) }],
|
|
4566
4825
|
isError: true
|
|
4567
4826
|
};
|
|
4568
4827
|
}
|
|
@@ -4582,7 +4841,7 @@ var RSSToolHandler = class {
|
|
|
4582
4841
|
},
|
|
4583
4842
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
4584
4843
|
try {
|
|
4585
|
-
const
|
|
4844
|
+
const id = resolveId(args);
|
|
4586
4845
|
const cached = await this.cache.get(`feed:${id}`);
|
|
4587
4846
|
if (cached) {
|
|
4588
4847
|
return { content: [{ type: "text", text: JSON.stringify({ success: true, feed: cached, from_cache: true }, null, 2) }] };
|
|
@@ -4672,7 +4931,8 @@ var RSSToolHandler = class {
|
|
|
4672
4931
|
},
|
|
4673
4932
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
4674
4933
|
try {
|
|
4675
|
-
const
|
|
4934
|
+
const id = resolveId(args);
|
|
4935
|
+
const { updates } = args;
|
|
4676
4936
|
await this.apiClient.updateFeed(id, updates);
|
|
4677
4937
|
await this.cache.delete(`feed:${id}`);
|
|
4678
4938
|
this.metrics.recordAPICall("update_feed", "success");
|
|
@@ -4698,7 +4958,7 @@ var RSSToolHandler = class {
|
|
|
4698
4958
|
},
|
|
4699
4959
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
4700
4960
|
try {
|
|
4701
|
-
const
|
|
4961
|
+
const id = resolveId(args);
|
|
4702
4962
|
await this.apiClient.deleteFeed(id);
|
|
4703
4963
|
await this.cache.delete(`feed:${id}`);
|
|
4704
4964
|
this.metrics.recordAPICall("delete_feed", "success");
|
|
@@ -4820,7 +5080,7 @@ var JobsToolHandler = class {
|
|
|
4820
5080
|
},
|
|
4821
5081
|
handler: /* @__PURE__ */ __name(async (args) => {
|
|
4822
5082
|
try {
|
|
4823
|
-
const
|
|
5083
|
+
const id = resolveId(args);
|
|
4824
5084
|
const job = await this.apiClient.getJob(id);
|
|
4825
5085
|
this.metrics.recordAPICall("get_job", "success");
|
|
4826
5086
|
return {
|