@ainyc/canonry 4.1.1 → 4.1.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/assets/assets/{index-Dtgn4FDp.js → index-BbhhYPML.js} +110 -110
- package/assets/index.html +1 -1
- package/dist/{chunk-NCWCPBOT.js → chunk-AXMSAMKN.js} +2 -1
- package/dist/{chunk-BQN6BBHI.js → chunk-JV6X6AFT.js} +20 -20
- package/dist/cli.js +16 -14
- package/dist/index.js +2 -2
- package/dist/{intelligence-service-EITZP4KG.js → intelligence-service-WPY4PDBU.js} +1 -1
- package/package.json +6 -6
package/assets/index.html
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<link rel="icon" type="image/png" sizes="32x32" href="./favicon-32.png" />
|
|
13
13
|
<link rel="apple-touch-icon" href="./apple-touch-icon.png" />
|
|
14
14
|
<title>Canonry</title>
|
|
15
|
-
<script type="module" crossorigin src="./assets/index-
|
|
15
|
+
<script type="module" crossorigin src="./assets/index-BbhhYPML.js"></script>
|
|
16
16
|
<link rel="stylesheet" crossorigin href="./assets/index-D7T5wSBj.css">
|
|
17
17
|
</head>
|
|
18
18
|
<body>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
CitationStates,
|
|
2
3
|
ContentActions,
|
|
3
4
|
RunKinds,
|
|
4
5
|
__export
|
|
@@ -2423,7 +2424,7 @@ var IntelligenceService = class {
|
|
|
2423
2424
|
return {
|
|
2424
2425
|
query: r.query ?? "",
|
|
2425
2426
|
provider: r.provider,
|
|
2426
|
-
cited: r.citationState ===
|
|
2427
|
+
cited: r.citationState === CitationStates.cited,
|
|
2427
2428
|
citationUrl: domains[0] ?? void 0,
|
|
2428
2429
|
competitorDomain: competitors2[0] ?? void 0
|
|
2429
2430
|
};
|
|
@@ -49,7 +49,7 @@ import {
|
|
|
49
49
|
runs,
|
|
50
50
|
schedules,
|
|
51
51
|
usageCounters
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-AXMSAMKN.js";
|
|
53
53
|
import {
|
|
54
54
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
55
55
|
AGENT_PROVIDER_IDS,
|
|
@@ -1946,7 +1946,7 @@ async function historyRoutes(app) {
|
|
|
1946
1946
|
for (const snap of allSnapshots) {
|
|
1947
1947
|
const key = `${snap.runId}:${snap.queryId}`;
|
|
1948
1948
|
const existing = deduped.get(key);
|
|
1949
|
-
if (!existing || !existing.answerMentioned && snap.answerMentioned || existing.answerMentioned === snap.answerMentioned && snap.citationState ===
|
|
1949
|
+
if (!existing || !existing.answerMentioned && snap.answerMentioned || existing.answerMentioned === snap.answerMentioned && snap.citationState === CitationStates.cited) {
|
|
1950
1950
|
deduped.set(key, snap);
|
|
1951
1951
|
}
|
|
1952
1952
|
}
|
|
@@ -1968,16 +1968,16 @@ async function historyRoutes(app) {
|
|
|
1968
1968
|
function computeTransitions(snaps) {
|
|
1969
1969
|
return snaps.map((snap, idx) => {
|
|
1970
1970
|
const run = projectRuns.find((r) => r.id === snap.runId);
|
|
1971
|
-
let transition = snap.citationState ===
|
|
1971
|
+
let transition = snap.citationState === CitationStates.cited ? "cited" : "not-cited";
|
|
1972
1972
|
let visibilityTransition = snap.answerMentioned ? "visible" : "not-visible";
|
|
1973
1973
|
if (idx === 0) {
|
|
1974
1974
|
transition = "new";
|
|
1975
1975
|
visibilityTransition = "new";
|
|
1976
1976
|
} else {
|
|
1977
1977
|
const prev = snaps[idx - 1];
|
|
1978
|
-
if (prev.citationState === "not-cited" && snap.citationState ===
|
|
1978
|
+
if (prev.citationState === CitationStates["not-cited"] && snap.citationState === CitationStates.cited) {
|
|
1979
1979
|
transition = "emerging";
|
|
1980
|
-
} else if (prev.citationState ===
|
|
1980
|
+
} else if (prev.citationState === CitationStates.cited && snap.citationState === CitationStates["not-cited"]) {
|
|
1981
1981
|
transition = "lost";
|
|
1982
1982
|
}
|
|
1983
1983
|
if (!prev.answerMentioned && snap.answerMentioned) {
|
|
@@ -2051,7 +2051,7 @@ async function historyRoutes(app) {
|
|
|
2051
2051
|
resolvedVisibilityState: resolveSnapshotVisibilityState(s, project)
|
|
2052
2052
|
};
|
|
2053
2053
|
const existing = map1.get(s.queryId);
|
|
2054
|
-
if (!existing || !existing.resolvedAnswerMentioned && resolved.resolvedAnswerMentioned || existing.resolvedAnswerMentioned === resolved.resolvedAnswerMentioned && resolved.citationState ===
|
|
2054
|
+
if (!existing || !existing.resolvedAnswerMentioned && resolved.resolvedAnswerMentioned || existing.resolvedAnswerMentioned === resolved.resolvedAnswerMentioned && resolved.citationState === CitationStates.cited) {
|
|
2055
2055
|
map1.set(s.queryId, resolved);
|
|
2056
2056
|
}
|
|
2057
2057
|
}
|
|
@@ -2063,7 +2063,7 @@ async function historyRoutes(app) {
|
|
|
2063
2063
|
resolvedVisibilityState: resolveSnapshotVisibilityState(s, project)
|
|
2064
2064
|
};
|
|
2065
2065
|
const existing = map2.get(s.queryId);
|
|
2066
|
-
if (!existing || !existing.resolvedAnswerMentioned && resolved.resolvedAnswerMentioned || existing.resolvedAnswerMentioned === resolved.resolvedAnswerMentioned && resolved.citationState ===
|
|
2066
|
+
if (!existing || !existing.resolvedAnswerMentioned && resolved.resolvedAnswerMentioned || existing.resolvedAnswerMentioned === resolved.resolvedAnswerMentioned && resolved.citationState === CitationStates.cited) {
|
|
2067
2067
|
map2.set(s.queryId, resolved);
|
|
2068
2068
|
}
|
|
2069
2069
|
}
|
|
@@ -2177,7 +2177,7 @@ async function analyticsRoutes(app) {
|
|
|
2177
2177
|
consistencyMap.set(s.queryId, entry);
|
|
2178
2178
|
}
|
|
2179
2179
|
entry.totalRuns.add(s.runId);
|
|
2180
|
-
if (s.citationState ===
|
|
2180
|
+
if (s.citationState === CitationStates.cited) entry.citedRuns.add(s.runId);
|
|
2181
2181
|
if (resolveSnapshotAnswerMentioned(s, project)) entry.mentionedRuns.add(s.runId);
|
|
2182
2182
|
}
|
|
2183
2183
|
}
|
|
@@ -2209,7 +2209,7 @@ async function analyticsRoutes(app) {
|
|
|
2209
2209
|
const notMentioned = [];
|
|
2210
2210
|
for (const [queryId, qSnapshots] of byQuery) {
|
|
2211
2211
|
const query = qSnapshots[0]?.query ?? "";
|
|
2212
|
-
const citedProviders = qSnapshots.filter((s) => s.citationState ===
|
|
2212
|
+
const citedProviders = qSnapshots.filter((s) => s.citationState === CitationStates.cited).map((s) => s.provider);
|
|
2213
2213
|
const mentionedProviders = qSnapshots.filter((s) => s.resolvedMentioned).map((s) => s.provider);
|
|
2214
2214
|
const competitorsCiting = /* @__PURE__ */ new Set();
|
|
2215
2215
|
for (const s of qSnapshots) {
|
|
@@ -2338,7 +2338,7 @@ function bucketSizeForSpan(spanDays) {
|
|
|
2338
2338
|
}
|
|
2339
2339
|
function computeProviderMetric(snapshots) {
|
|
2340
2340
|
const total = snapshots.length;
|
|
2341
|
-
const cited = snapshots.filter((s) => s.citationState ===
|
|
2341
|
+
const cited = snapshots.filter((s) => s.citationState === CitationStates.cited).length;
|
|
2342
2342
|
const mentionedCount = snapshots.filter((s) => s.resolvedMentioned).length;
|
|
2343
2343
|
return {
|
|
2344
2344
|
citationRate: total > 0 ? Math.round(cited / total * 1e4) / 1e4 : 0,
|
|
@@ -2967,7 +2967,7 @@ function renderCitationMatrix(scorecard) {
|
|
|
2967
2967
|
if (!cell) {
|
|
2968
2968
|
return '<td><span class="cell-pending">\u2014</span></td>';
|
|
2969
2969
|
}
|
|
2970
|
-
if (cell.citationState ===
|
|
2970
|
+
if (cell.citationState === CitationStates.cited) {
|
|
2971
2971
|
return '<td><span class="cell-cited">Cited</span></td>';
|
|
2972
2972
|
}
|
|
2973
2973
|
return '<td><span class="cell-not-cited">Not cited</span></td>';
|
|
@@ -3916,13 +3916,13 @@ function buildCitationScorecard(snapshots, queryLookup) {
|
|
|
3916
3916
|
const pi = providerList.indexOf(snap.provider);
|
|
3917
3917
|
if (qi < 0 || pi < 0) continue;
|
|
3918
3918
|
matrix[qi][pi] = {
|
|
3919
|
-
citationState: snap.citationState ===
|
|
3919
|
+
citationState: snap.citationState === CitationStates.cited ? CitationStates.cited : CitationStates["not-cited"],
|
|
3920
3920
|
answerMentioned: snap.answerMentioned ?? null,
|
|
3921
3921
|
model: snap.model
|
|
3922
3922
|
};
|
|
3923
3923
|
const counts = providerCounts.get(snap.provider) ?? { cited: 0, total: 0 };
|
|
3924
3924
|
counts.total++;
|
|
3925
|
-
if (snap.citationState ===
|
|
3925
|
+
if (snap.citationState === CitationStates.cited) counts.cited++;
|
|
3926
3926
|
providerCounts.set(snap.provider, counts);
|
|
3927
3927
|
}
|
|
3928
3928
|
const providerRates = providerList.map((provider) => {
|
|
@@ -4319,10 +4319,10 @@ function buildCitationsTrend(db, projectId, queryLookup) {
|
|
|
4319
4319
|
for (const snap of snaps) {
|
|
4320
4320
|
if (!queryLookup.byId.has(snap.queryId)) continue;
|
|
4321
4321
|
considered++;
|
|
4322
|
-
if (snap.citationState ===
|
|
4322
|
+
if (snap.citationState === CitationStates.cited) cited++;
|
|
4323
4323
|
const counts = providerCounts.get(snap.provider) ?? { cited: 0, total: 0 };
|
|
4324
4324
|
counts.total++;
|
|
4325
|
-
if (snap.citationState ===
|
|
4325
|
+
if (snap.citationState === CitationStates.cited) counts.cited++;
|
|
4326
4326
|
providerCounts.set(snap.provider, counts);
|
|
4327
4327
|
}
|
|
4328
4328
|
if (considered === 0) continue;
|
|
@@ -4523,7 +4523,7 @@ function buildProjectReport(db, projectName) {
|
|
|
4523
4523
|
for (const snap of latestSnapshots) {
|
|
4524
4524
|
if (!queryLookup.byId.has(snap.queryId)) continue;
|
|
4525
4525
|
latestConsidered++;
|
|
4526
|
-
if (snap.citationState ===
|
|
4526
|
+
if (snap.citationState === CitationStates.cited) latestCited++;
|
|
4527
4527
|
}
|
|
4528
4528
|
const citationRate = latestConsidered > 0 ? Math.round(latestCited / latestConsidered * 100) : 0;
|
|
4529
4529
|
const trendBaseline = isTrendBaseline(citationsTrend);
|
|
@@ -4916,7 +4916,7 @@ function summarizeLatestRun(app, run) {
|
|
|
4916
4916
|
const perQuery = /* @__PURE__ */ new Map();
|
|
4917
4917
|
const perProvider = /* @__PURE__ */ new Map();
|
|
4918
4918
|
for (const row of rows) {
|
|
4919
|
-
const cited = row.citationState ===
|
|
4919
|
+
const cited = row.citationState === CitationStates.cited;
|
|
4920
4920
|
if (!perQuery.has(row.queryId) || cited) {
|
|
4921
4921
|
perQuery.set(row.queryId, cited);
|
|
4922
4922
|
}
|
|
@@ -4953,7 +4953,7 @@ function summarizeTransitions(app, latest, previous) {
|
|
|
4953
4953
|
}).from(querySnapshots).where(eq15(querySnapshots.runId, runId)).all();
|
|
4954
4954
|
const map = /* @__PURE__ */ new Map();
|
|
4955
4955
|
for (const row of rows) {
|
|
4956
|
-
const cited = row.citationState ===
|
|
4956
|
+
const cited = row.citationState === CitationStates.cited;
|
|
4957
4957
|
if (!map.has(row.queryId) || cited) map.set(row.queryId, cited);
|
|
4958
4958
|
}
|
|
4959
4959
|
return map;
|
|
@@ -10814,8 +10814,8 @@ async function cdpRoutes(app, opts) {
|
|
|
10814
10814
|
let total = 0;
|
|
10815
10815
|
const queryResults = [...byQuery.values()].map(({ query, api, browser }) => {
|
|
10816
10816
|
total++;
|
|
10817
|
-
const apiCited = api?.citationState ===
|
|
10818
|
-
const browserCited = browser?.citationState ===
|
|
10817
|
+
const apiCited = api?.citationState === CitationStates.cited;
|
|
10818
|
+
const browserCited = browser?.citationState === CitationStates.cited;
|
|
10819
10819
|
let agreement;
|
|
10820
10820
|
if (!api && !browser) {
|
|
10821
10821
|
agreement = "no-data";
|
package/dist/cli.js
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
setGoogleAuthConfig,
|
|
19
19
|
showFirstRunNotice,
|
|
20
20
|
trackEvent
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-JV6X6AFT.js";
|
|
22
22
|
import {
|
|
23
23
|
CliError,
|
|
24
24
|
EXIT_SYSTEM_ERROR,
|
|
@@ -45,11 +45,12 @@ import {
|
|
|
45
45
|
projects,
|
|
46
46
|
querySnapshots,
|
|
47
47
|
runs
|
|
48
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-AXMSAMKN.js";
|
|
49
49
|
import {
|
|
50
50
|
CcReleaseSyncStatuses,
|
|
51
51
|
CheckScopes,
|
|
52
52
|
CheckStatuses,
|
|
53
|
+
CitationStates,
|
|
53
54
|
CodingAgents,
|
|
54
55
|
ProviderNames,
|
|
55
56
|
RunKinds,
|
|
@@ -579,7 +580,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
579
580
|
return result;
|
|
580
581
|
}
|
|
581
582
|
async function backfillInsightsCommand(project, opts) {
|
|
582
|
-
const { IntelligenceService } = await import("./intelligence-service-
|
|
583
|
+
const { IntelligenceService } = await import("./intelligence-service-WPY4PDBU.js");
|
|
583
584
|
const config = loadConfig();
|
|
584
585
|
const db = createClient(config.database);
|
|
585
586
|
migrate(db);
|
|
@@ -4597,8 +4598,8 @@ async function testNotification(project, id, format) {
|
|
|
4597
4598
|
var EVENT_DESCRIPTIONS = {
|
|
4598
4599
|
"citation.lost": "A query lost its citation status",
|
|
4599
4600
|
"citation.gained": "A query gained citation status",
|
|
4600
|
-
"run.completed": "
|
|
4601
|
-
"run.failed": "
|
|
4601
|
+
"run.completed": "An AEO sweep completed successfully",
|
|
4602
|
+
"run.failed": "An AEO sweep failed",
|
|
4602
4603
|
"insight.critical": "A critical-severity insight was generated",
|
|
4603
4604
|
"insight.high": "A high-severity insight was generated"
|
|
4604
4605
|
};
|
|
@@ -4889,7 +4890,7 @@ async function showEvidence(project, format) {
|
|
|
4889
4890
|
if (format === "json") {
|
|
4890
4891
|
const enriched = timeline.map((entry) => ({
|
|
4891
4892
|
...entry,
|
|
4892
|
-
cited: entry.runs[entry.runs.length - 1]?.citationState ===
|
|
4893
|
+
cited: entry.runs[entry.runs.length - 1]?.citationState === CitationStates.cited
|
|
4893
4894
|
}));
|
|
4894
4895
|
console.log(JSON.stringify(enriched, null, 2));
|
|
4895
4896
|
return;
|
|
@@ -4903,13 +4904,13 @@ async function showEvidence(project, format) {
|
|
|
4903
4904
|
for (const entry of timeline) {
|
|
4904
4905
|
const latest = entry.runs[entry.runs.length - 1];
|
|
4905
4906
|
if (!latest) continue;
|
|
4906
|
-
const state = latest.citationState ===
|
|
4907
|
+
const state = latest.citationState === CitationStates.cited ? "\u2713 cited" : "\u2717 not-cited";
|
|
4907
4908
|
const transition = latest.transition !== latest.citationState ? ` (${latest.transition})` : "";
|
|
4908
4909
|
console.log(` ${state}${transition} ${entry.query}`);
|
|
4909
4910
|
}
|
|
4910
4911
|
console.log(`
|
|
4911
4912
|
Queries: ${timeline.length}`);
|
|
4912
|
-
const cited = timeline.filter((e) => e.runs[e.runs.length - 1]?.citationState ===
|
|
4913
|
+
const cited = timeline.filter((e) => e.runs[e.runs.length - 1]?.citationState === CitationStates.cited).length;
|
|
4913
4914
|
console.log(` Cited: ${cited} / ${timeline.length}`);
|
|
4914
4915
|
}
|
|
4915
4916
|
|
|
@@ -5750,11 +5751,12 @@ function printRunDetail(run) {
|
|
|
5750
5751
|
}
|
|
5751
5752
|
if (run.snapshots && run.snapshots.length > 0) {
|
|
5752
5753
|
console.log(`
|
|
5753
|
-
Snapshots: ${run.snapshots.length}`);
|
|
5754
|
+
Snapshots: ${run.snapshots.length} (cell = [citation][mention]; C=cited c=not, M=mentioned m=not, \u2013=no data)`);
|
|
5754
5755
|
for (const s of run.snapshots) {
|
|
5755
|
-
const
|
|
5756
|
+
const citationGlyph = s.citationState === CitationStates.cited ? "C" : "c";
|
|
5757
|
+
const mentionGlyph = typeof s.answerMentioned === "boolean" ? s.answerMentioned ? "M" : "m" : "\u2013";
|
|
5756
5758
|
const modelLabel = s.model ? ` (${s.model})` : "";
|
|
5757
|
-
console.log(` ${
|
|
5759
|
+
console.log(` [${citationGlyph}${mentionGlyph}] ${s.provider}${modelLabel} ${s.query}`);
|
|
5758
5760
|
}
|
|
5759
5761
|
}
|
|
5760
5762
|
}
|
|
@@ -6730,7 +6732,7 @@ function renderCover(pdf, report) {
|
|
|
6730
6732
|
minute: "2-digit"
|
|
6731
6733
|
}));
|
|
6732
6734
|
pdf.keyValue("AEO Audit", `${report.audit.overallScore}/100 (${report.audit.overallGrade})`);
|
|
6733
|
-
pdf.keyValue("Visibility Gap", report.summary.visibilityGap);
|
|
6735
|
+
pdf.keyValue("Visibility Gap (Citations + Mentions)", report.summary.visibilityGap);
|
|
6734
6736
|
pdf.paragraph(report.profile.summary, { size: 11, color: INK, lineHeight: 16 });
|
|
6735
6737
|
pdf.rule();
|
|
6736
6738
|
}
|
|
@@ -6885,7 +6887,7 @@ function formatSnapshotMarkdown(report) {
|
|
|
6885
6887
|
lines.push(`**Generated:** ${new Date(report.generatedAt).toLocaleString("en-US", { year: "numeric", month: "long", day: "numeric", hour: "numeric", minute: "2-digit" })}`);
|
|
6886
6888
|
lines.push(`**AEO Audit Score:** ${report.audit.overallScore}/100 (${report.audit.overallGrade})`);
|
|
6887
6889
|
lines.push("");
|
|
6888
|
-
lines.push("## Visibility Gap");
|
|
6890
|
+
lines.push("## Visibility Gap (Citations + Mentions)");
|
|
6889
6891
|
lines.push("");
|
|
6890
6892
|
lines.push(report.summary.visibilityGap);
|
|
6891
6893
|
lines.push("");
|
|
@@ -7250,7 +7252,7 @@ function printSummary(data) {
|
|
|
7250
7252
|
queriesMentionedOnly,
|
|
7251
7253
|
queriesInvisible
|
|
7252
7254
|
} = data.summary;
|
|
7253
|
-
console.log("
|
|
7255
|
+
console.log("AEO visibility (citations + mentions)");
|
|
7254
7256
|
if (data.summary.latestRunAt) {
|
|
7255
7257
|
console.log(`Latest run: ${data.summary.latestRunAt}`);
|
|
7256
7258
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createServer
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-JV6X6AFT.js";
|
|
4
4
|
import {
|
|
5
5
|
loadConfig
|
|
6
6
|
} from "./chunk-KCETXLDF.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-AXMSAMKN.js";
|
|
8
8
|
import "./chunk-O5JZQUPX.js";
|
|
9
9
|
export {
|
|
10
10
|
createServer,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainyc/canonry",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Agent-first open-source AEO operating platform - track how answer engines cite your domain",
|
|
6
6
|
"license": "FSL-1.1-ALv2",
|
|
@@ -61,19 +61,19 @@
|
|
|
61
61
|
"tsx": "^4.19.0",
|
|
62
62
|
"@ainyc/canonry-api-routes": "0.0.0",
|
|
63
63
|
"@ainyc/canonry-config": "0.0.0",
|
|
64
|
-
"@ainyc/canonry-contracts": "0.0.0",
|
|
65
64
|
"@ainyc/canonry-db": "0.0.0",
|
|
65
|
+
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
66
66
|
"@ainyc/canonry-intelligence": "0.0.0",
|
|
67
|
+
"@ainyc/canonry-contracts": "0.0.0",
|
|
67
68
|
"@ainyc/canonry-integration-commoncrawl": "0.0.0",
|
|
68
69
|
"@ainyc/canonry-integration-google": "0.0.0",
|
|
69
|
-
"@ainyc/canonry-integration-bing": "0.0.0",
|
|
70
70
|
"@ainyc/canonry-provider-cdp": "0.0.0",
|
|
71
|
-
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
72
71
|
"@ainyc/canonry-provider-claude": "0.0.0",
|
|
72
|
+
"@ainyc/canonry-integration-wordpress": "0.0.0",
|
|
73
73
|
"@ainyc/canonry-provider-gemini": "0.0.0",
|
|
74
74
|
"@ainyc/canonry-provider-local": "0.0.0",
|
|
75
|
-
"@ainyc/canonry-provider-
|
|
76
|
-
"@ainyc/canonry-provider-
|
|
75
|
+
"@ainyc/canonry-provider-openai": "0.0.0",
|
|
76
|
+
"@ainyc/canonry-provider-perplexity": "0.0.0"
|
|
77
77
|
},
|
|
78
78
|
"scripts": {
|
|
79
79
|
"build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",
|