@canonry/canonry 5.30.1 → 5.32.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.
Files changed (24) hide show
  1. package/assets/assets/{AuditHistoryPanel-8GPJdEWL.js → AuditHistoryPanel-DW2aeqJP.js} +1 -1
  2. package/assets/assets/{BacklinksPage-8-KPXFtA.js → BacklinksPage-DroPpjd3.js} +1 -1
  3. package/assets/assets/{HistoryPage-CKgF71m5.js → HistoryPage-2o6p-ZDF.js} +1 -1
  4. package/assets/assets/{MeasurementPropertyPage-nfGYHl6C.js → MeasurementPropertyPage-VTGLyVuD.js} +1 -1
  5. package/assets/assets/{ProjectPage-BPtdO-Gp.js → ProjectPage-CXV64SBB.js} +1 -1
  6. package/assets/assets/{RunRow-C3CRRfb4.js → RunRow-CIhSIAoR.js} +1 -1
  7. package/assets/assets/{RunsPage-BvCCjtqM.js → RunsPage-lO9xMTSl.js} +1 -1
  8. package/assets/assets/{SettingsPage-B1QuP6Cv.js → SettingsPage-CBwns7cb.js} +1 -1
  9. package/assets/assets/{SiteHealthSection-DgM3aTd-.js → SiteHealthSection-C372wrfT.js} +3 -3
  10. package/assets/assets/{TrafficPage-DEUDhBXG.js → TrafficPage-DGyS-IjJ.js} +1 -1
  11. package/assets/assets/{TrafficSourceDetailPage-gpgLsGA1.js → TrafficSourceDetailPage-BBaz_ivE.js} +1 -1
  12. package/assets/assets/{extract-error-message-CH4G5kw6.js → extract-error-message-QcHrDOjc.js} +1 -1
  13. package/assets/assets/{index-B2qeAPfR.js → index-CbnQjcJj.js} +3 -3
  14. package/assets/assets/{react-sigma_core.esm.min-CG4hSMQ3.js → react-sigma_core.esm.min-D9tjGma4.js} +1 -1
  15. package/assets/assets/{v2-overview-adapter-QNwqt0UG.js → v2-overview-adapter-CLlJkExr.js} +1 -1
  16. package/assets/index.html +1 -1
  17. package/dist/{chunk-LLVE7B3V.js → chunk-6UO23AKO.js} +150 -67
  18. package/dist/{chunk-TPJ4MMZ6.js → chunk-7YS62CJ4.js} +111 -3
  19. package/dist/{chunk-TWYIUHJU.js → chunk-YVWYQBXW.js} +1 -1
  20. package/dist/cli.js +4 -4
  21. package/dist/{demo-server-EU5DGFB3.js → demo-server-ERFY4Q2P.js} +2 -2
  22. package/dist/index.js +3 -3
  23. package/dist/{intelligence-service-SUFG6ICC.js → intelligence-service-PULUYOPR.js} +1 -1
  24. package/package.json +12 -13
@@ -2732,7 +2732,8 @@ var llmUsageEvents = sqliteTable("llm_usage_events", {
2732
2732
  id: text("id").primaryKey(),
2733
2733
  projectId: text("project_id").references(() => projects.id, { onDelete: "cascade" }),
2734
2734
  runId: text("run_id").references(() => runs.id, { onDelete: "set null" }),
2735
- agentSessionId: text("agent_session_id").references(() => agentSessions.id, { onDelete: "set null" }),
2735
+ /** The Aero conversation id: `agent_sessions.id` while active, `agent_conversations.id` once archived. Not a foreign key (v165). */
2736
+ agentSessionId: text("agent_session_id"),
2736
2737
  feature: text("feature").notNull(),
2737
2738
  provider: text("provider").notNull(),
2738
2739
  model: text("model").notNull(),
@@ -2756,7 +2757,8 @@ var llmUsageEvents = sqliteTable("llm_usage_events", {
2756
2757
  var agentToolEvents = sqliteTable("agent_tool_events", {
2757
2758
  id: text("id").primaryKey(),
2758
2759
  projectId: text("project_id").references(() => projects.id, { onDelete: "cascade" }),
2759
- agentSessionId: text("agent_session_id").references(() => agentSessions.id, { onDelete: "set null" }),
2760
+ /** The Aero conversation id, as on `llm_usage_events`. Not a foreign key (v165). */
2761
+ agentSessionId: text("agent_session_id"),
2760
2762
  toolCallId: text("tool_call_id").notNull(),
2761
2763
  toolName: text("tool_name").notNull(),
2762
2764
  assistantResponseId: text("assistant_response_id"),
@@ -8157,8 +8159,106 @@ var MIGRATION_VERSIONS = [
8157
8159
  `CREATE UNIQUE INDEX IF NOT EXISTS idx_sentiment_attempt_number ON sentiment_attempts(work_item_id, attempt_number)`,
8158
8160
  `CREATE INDEX IF NOT EXISTS idx_sentiment_attempt_dispatch ON sentiment_attempts(dispatched_at)`
8159
8161
  ]
8162
+ },
8163
+ {
8164
+ // An Aero conversation id lives in `agent_sessions` while it is active and
8165
+ // in `agent_conversations` once archived, and one foreign key can reference
8166
+ // only one of them. Keyed to `agent_sessions`, the usage and tool ledgers
8167
+ // made "new conversation" fail after any turn (the handler re-keyed the
8168
+ // active row) and nulled a conversation's rows when another was resumed.
8169
+ // The hook rebuilds both tables with `agent_session_id` as a plain indexed
8170
+ // id; see `dropAeroLedgerConversationKeys`.
8171
+ version: 165,
8172
+ name: "aero-ledger-conversation-ids",
8173
+ statements: [],
8174
+ run: dropAeroLedgerConversationKeys
8160
8175
  }
8161
8176
  ];
8177
+ var AERO_LEDGER_REBUILDS = [
8178
+ {
8179
+ table: "llm_usage_events",
8180
+ statements: [
8181
+ `CREATE TABLE llm_usage_events_v165 (
8182
+ id TEXT PRIMARY KEY,
8183
+ project_id TEXT REFERENCES projects(id) ON DELETE CASCADE,
8184
+ run_id TEXT REFERENCES runs(id) ON DELETE SET NULL,
8185
+ agent_session_id TEXT,
8186
+ feature TEXT NOT NULL,
8187
+ provider TEXT NOT NULL,
8188
+ model TEXT NOT NULL,
8189
+ response_id TEXT,
8190
+ input_tokens INTEGER NOT NULL DEFAULT 0,
8191
+ output_tokens INTEGER NOT NULL DEFAULT 0,
8192
+ cache_read_tokens INTEGER NOT NULL DEFAULT 0,
8193
+ cache_write_tokens INTEGER NOT NULL DEFAULT 0,
8194
+ total_tokens INTEGER NOT NULL DEFAULT 0,
8195
+ cost_millicents INTEGER NOT NULL DEFAULT 0,
8196
+ prompt_family TEXT,
8197
+ prompt_version TEXT,
8198
+ metadata TEXT,
8199
+ created_at TEXT NOT NULL
8200
+ )`,
8201
+ `INSERT INTO llm_usage_events_v165 (
8202
+ id, project_id, run_id, agent_session_id, feature, provider, model, response_id, input_tokens, output_tokens,
8203
+ cache_read_tokens, cache_write_tokens, total_tokens, cost_millicents, prompt_family, prompt_version, metadata, created_at
8204
+ )
8205
+ SELECT u.id, p.id, r.id, u.agent_session_id, u.feature, u.provider, u.model, u.response_id, u.input_tokens, u.output_tokens,
8206
+ u.cache_read_tokens, u.cache_write_tokens, u.total_tokens, u.cost_millicents, u.prompt_family, u.prompt_version, u.metadata, u.created_at
8207
+ FROM llm_usage_events u
8208
+ LEFT JOIN projects p ON p.id = u.project_id
8209
+ LEFT JOIN runs r ON r.id = u.run_id`,
8210
+ `DROP TABLE llm_usage_events`,
8211
+ `ALTER TABLE llm_usage_events_v165 RENAME TO llm_usage_events`,
8212
+ `CREATE INDEX IF NOT EXISTS idx_llm_usage_project_created ON llm_usage_events(project_id, created_at)`,
8213
+ `CREATE INDEX IF NOT EXISTS idx_llm_usage_feature_created ON llm_usage_events(feature, created_at)`,
8214
+ `CREATE INDEX IF NOT EXISTS idx_llm_usage_session_created ON llm_usage_events(agent_session_id, created_at)`,
8215
+ `CREATE INDEX IF NOT EXISTS idx_llm_usage_run_created ON llm_usage_events(run_id, created_at)`
8216
+ ]
8217
+ },
8218
+ {
8219
+ table: "agent_tool_events",
8220
+ statements: [
8221
+ `CREATE TABLE agent_tool_events_v165 (
8222
+ id TEXT PRIMARY KEY,
8223
+ project_id TEXT REFERENCES projects(id) ON DELETE CASCADE,
8224
+ agent_session_id TEXT,
8225
+ tool_call_id TEXT NOT NULL,
8226
+ tool_name TEXT NOT NULL,
8227
+ assistant_response_id TEXT,
8228
+ provider TEXT,
8229
+ model TEXT,
8230
+ status TEXT NOT NULL,
8231
+ duration_ms INTEGER NOT NULL DEFAULT 0,
8232
+ args_bytes INTEGER NOT NULL DEFAULT 0,
8233
+ result_text_chars INTEGER NOT NULL DEFAULT 0,
8234
+ result_bytes INTEGER NOT NULL DEFAULT 0,
8235
+ metadata TEXT,
8236
+ created_at TEXT NOT NULL
8237
+ )`,
8238
+ `INSERT INTO agent_tool_events_v165 (
8239
+ id, project_id, agent_session_id, tool_call_id, tool_name, assistant_response_id, provider, model, status,
8240
+ duration_ms, args_bytes, result_text_chars, result_bytes, metadata, created_at
8241
+ )
8242
+ SELECT t.id, p.id, t.agent_session_id, t.tool_call_id, t.tool_name, t.assistant_response_id, t.provider, t.model, t.status,
8243
+ t.duration_ms, t.args_bytes, t.result_text_chars, t.result_bytes, t.metadata, t.created_at
8244
+ FROM agent_tool_events t
8245
+ LEFT JOIN projects p ON p.id = t.project_id`,
8246
+ `DROP TABLE agent_tool_events`,
8247
+ `ALTER TABLE agent_tool_events_v165 RENAME TO agent_tool_events`,
8248
+ `CREATE INDEX IF NOT EXISTS idx_agent_tool_events_project_created ON agent_tool_events(project_id, created_at)`,
8249
+ `CREATE INDEX IF NOT EXISTS idx_agent_tool_events_session_created ON agent_tool_events(agent_session_id, created_at)`,
8250
+ `CREATE INDEX IF NOT EXISTS idx_agent_tool_events_tool_created ON agent_tool_events(tool_name, created_at)`,
8251
+ `CREATE INDEX IF NOT EXISTS idx_agent_tool_events_status_created ON agent_tool_events(status, created_at)`
8252
+ ]
8253
+ }
8254
+ ];
8255
+ function dropAeroLedgerConversationKeys(tx) {
8256
+ for (const ledger of AERO_LEDGER_REBUILDS) {
8257
+ const keys = tx.all(sql2.raw(`PRAGMA foreign_key_list('${ledger.table}')`));
8258
+ if (!keys.some((key) => key.table === "agent_sessions")) continue;
8259
+ for (const statement of ledger.statements) tx.run(sql2.raw(statement));
8260
+ }
8261
+ }
8162
8262
  function addRunsMeasurementPlanVersionForeignKey(tx) {
8163
8263
  const tableSqlRow = tx.all(sql2.raw("SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'runs'"));
8164
8264
  const tableSql = tableSqlRow[0]?.sql;
@@ -13218,11 +13318,17 @@ function registerAgentConversationRoutes(app, opts) {
13218
13318
  prepare(project.name);
13219
13319
  const existing = activeRow(project.id);
13220
13320
  if (!existing) runtime.getOrCreate(project.name);
13321
+ if (!activeRow(project.id)) {
13322
+ runtime.reset(project.name);
13323
+ runtime.getOrCreate(project.name);
13324
+ }
13221
13325
  const current = activeRow(project.id);
13326
+ if (!current) throw notFound("conversation", id);
13222
13327
  const now = (/* @__PURE__ */ new Date()).toISOString();
13223
13328
  db.transaction((tx) => {
13224
13329
  if (existing) archive(tx, current);
13225
- tx.update(agentSessions).set({ id, messages: "[]", followUpQueue: "[]", createdAt: now, updatedAt: now }).where(eq6(agentSessions.projectId, project.id)).run();
13330
+ tx.delete(agentSessions).where(eq6(agentSessions.projectId, project.id)).run();
13331
+ tx.insert(agentSessions).values({ ...current, id, messages: "[]", followUpQueue: "[]", createdAt: now, updatedAt: now }).run();
13226
13332
  writeAuditLog(tx, auditFromRequest(request, { projectId: project.id, actor: "api", action: "agent.conversation.created", entityType: "agent-conversation", entityId: id }));
13227
13333
  });
13228
13334
  runtime.reset(project.name);
@@ -13268,6 +13374,8 @@ function registerAgentConversationRoutes(app, opts) {
13268
13374
  db.transaction((tx) => {
13269
13375
  tx.delete(agentConversations).where(and2(eq6(agentConversations.projectId, project.id), eq6(agentConversations.id, id))).run();
13270
13376
  if (isActive) tx.delete(agentSessions).where(eq6(agentSessions.projectId, project.id)).run();
13377
+ tx.update(llmUsageEvents).set({ agentSessionId: null }).where(and2(eq6(llmUsageEvents.projectId, project.id), eq6(llmUsageEvents.agentSessionId, id))).run();
13378
+ tx.update(agentToolEvents).set({ agentSessionId: null }).where(and2(eq6(agentToolEvents.projectId, project.id), eq6(agentToolEvents.agentSessionId, id))).run();
13271
13379
  const prefix = `compaction:${id}:`;
13272
13380
  const notes = tx.select().from(agentMemory).where(and2(eq6(agentMemory.projectId, project.id), like(agentMemory.key, "compaction:%"))).all();
13273
13381
  for (const note of notes) if (note.key.startsWith(prefix)) tx.delete(agentMemory).where(eq6(agentMemory.id, note.id)).run();
@@ -5,7 +5,7 @@ import {
5
5
  siteCrawlGraphNodes,
6
6
  siteCrawlPages,
7
7
  siteCrawlSnapshots
8
- } from "./chunk-TPJ4MMZ6.js";
8
+ } from "./chunk-7YS62CJ4.js";
9
9
  import {
10
10
  SITE_CRAWL_GRAPH_MAX_EDGES,
11
11
  SITE_CRAWL_GRAPH_MAX_NODES,
package/dist/cli.js CHANGED
@@ -35,7 +35,7 @@ import {
35
35
  trackCliCommandFinished,
36
36
  trackEvent,
37
37
  waitForServerRuntimeStartup
38
- } from "./chunk-LLVE7B3V.js";
38
+ } from "./chunk-6UO23AKO.js";
39
39
  import {
40
40
  autoSyncSkills,
41
41
  formatAutoSyncNotice
@@ -62,7 +62,7 @@ import {
62
62
  trustedProxiesProblem,
63
63
  trustedProxyProblem
64
64
  } from "./chunk-RB2F4D3Z.js";
65
- import "./chunk-TWYIUHJU.js";
65
+ import "./chunk-YVWYQBXW.js";
66
66
  import {
67
67
  CliError,
68
68
  EXIT_SYSTEM_ERROR,
@@ -89,7 +89,7 @@ import {
89
89
  queries,
90
90
  renderReportHtml,
91
91
  runs
92
- } from "./chunk-TPJ4MMZ6.js";
92
+ } from "./chunk-7YS62CJ4.js";
93
93
  import {
94
94
  AdsDeliverySnapshotStatuses,
95
95
  AdsHistoricalCampaignRollupStatuses,
@@ -720,7 +720,7 @@ function parseDemoTrustedProxies(values) {
720
720
  async function demoCommand(options) {
721
721
  const { host, port } = parseDemoListenOptions(options);
722
722
  const trustProxy = parseDemoTrustedProxies(options.trustProxy);
723
- const { createDemoServer } = await import("./demo-server-EU5DGFB3.js");
723
+ const { createDemoServer } = await import("./demo-server-ERFY4Q2P.js");
724
724
  const app = await createDemoServer({ trustProxy });
725
725
  let stopping = false;
726
726
  const stop = () => {
@@ -5,7 +5,7 @@ import {
5
5
  computeFactorAverages,
6
6
  layoutSiteCrawlGraphInput,
7
7
  persistSiteCrawlGraphLayout
8
- } from "./chunk-TWYIUHJU.js";
8
+ } from "./chunk-YVWYQBXW.js";
9
9
  import {
10
10
  PACKAGE_VERSION,
11
11
  canonryMcpTools
@@ -85,7 +85,7 @@ import {
85
85
  siteCrawlPages,
86
86
  siteCrawlSnapshots,
87
87
  trafficSources
88
- } from "./chunk-TPJ4MMZ6.js";
88
+ } from "./chunk-7YS62CJ4.js";
89
89
  import {
90
90
  RunKinds,
91
91
  SiteCrawlFetchStates,
package/dist/index.js CHANGED
@@ -3,13 +3,13 @@ import {
3
3
  createGoogleMarketingCredentialStore,
4
4
  createGoogleMarketingRuntime,
5
5
  createServer
6
- } from "./chunk-LLVE7B3V.js";
6
+ } from "./chunk-6UO23AKO.js";
7
7
  import {
8
8
  loadConfig
9
9
  } from "./chunk-WZL73LY3.js";
10
- import "./chunk-TWYIUHJU.js";
10
+ import "./chunk-YVWYQBXW.js";
11
11
  import "./chunk-DFIK6IPP.js";
12
- import "./chunk-TPJ4MMZ6.js";
12
+ import "./chunk-7YS62CJ4.js";
13
13
  import "./chunk-RCX6I3DX.js";
14
14
  export {
15
15
  GoogleMarketingRuntimeError,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  HISTORY_WINDOW_RUNS,
3
3
  IntelligenceService
4
- } from "./chunk-TPJ4MMZ6.js";
4
+ } from "./chunk-7YS62CJ4.js";
5
5
  import "./chunk-RCX6I3DX.js";
6
6
  export {
7
7
  HISTORY_WINDOW_RUNS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canonry/canonry",
3
- "version": "5.30.1",
3
+ "version": "5.32.0",
4
4
  "type": "module",
5
5
  "description": "Self-hosted AI visibility (AEO) platform: track how ChatGPT, Claude, Gemini, and Perplexity cite your domain, join it with Search Console, GA4, server-side traffic, and paid media, and fix what you find through agent tools (CLI, REST, MCP). Local SQLite.",
6
6
  "keywords": [
@@ -53,7 +53,7 @@
53
53
  "LICENSE"
54
54
  ],
55
55
  "engines": {
56
- "node": ">=22.14.0 <27"
56
+ "node": ">=22.19.0 <27"
57
57
  },
58
58
  "dependencies": {
59
59
  "@anthropic-ai/sdk": "^0.91.1",
@@ -61,10 +61,9 @@
61
61
  "@fastify/rate-limit": "^11.2.0",
62
62
  "@fastify/static": "^9.1.1",
63
63
  "@google/genai": "^1.46.0",
64
- "@mariozechner/pi-agent-core": "0.67.6",
65
- "@mariozechner/pi-ai": "0.67.6",
64
+ "@earendil-works/pi-agent-core": "0.87.1",
65
+ "@earendil-works/pi-ai": "0.87.1",
66
66
  "@modelcontextprotocol/sdk": "^1.29.0",
67
- "@sinclair/typebox": "^0.34.41",
68
67
  "better-sqlite3": "^12.11.1",
69
68
  "chrome-remote-interface": "^0.33.2",
70
69
  "cron-parser": "^5.5.0",
@@ -86,32 +85,32 @@
86
85
  "@types/node-cron": "^3.0.11",
87
86
  "tsup": "^8.5.1",
88
87
  "tsx": "^4.19.0",
88
+ "@ainyc/canonry-web": "0.0.0",
89
89
  "@ainyc/canonry-api-client": "0.0.0",
90
90
  "@ainyc/canonry-api-routes": "0.0.0",
91
91
  "@ainyc/canonry-config": "0.0.0",
92
- "@ainyc/canonry-web": "0.0.0",
93
- "@ainyc/canonry-contracts": "0.0.0",
94
92
  "@ainyc/canonry-db": "0.0.0",
93
+ "@ainyc/canonry-contracts": "0.0.0",
95
94
  "@ainyc/canonry-integration-bing": "0.0.0",
96
95
  "@ainyc/canonry-integration-cloud-run": "0.0.0",
97
- "@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
96
+ "@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
98
97
  "@ainyc/canonry-integration-google": "0.0.0",
99
- "@ainyc/canonry-integration-commoncrawl": "0.0.0",
100
98
  "@ainyc/canonry-integration-google-ads": "0.0.0",
99
+ "@ainyc/canonry-integration-cloudflare-worker": "0.0.0",
100
+ "@ainyc/canonry-integration-commoncrawl": "0.0.0",
101
+ "@ainyc/canonry-integration-google-business-profile": "0.0.0",
101
102
  "@ainyc/canonry-integration-google-places": "0.0.0",
102
103
  "@ainyc/canonry-integration-google-tag-manager": "0.0.0",
103
104
  "@ainyc/canonry-integration-openai-ads": "0.0.0",
104
- "@ainyc/canonry-integration-google-business-profile": "0.0.0",
105
- "@ainyc/canonry-integration-cloudflare-queue": "0.0.0",
106
105
  "@ainyc/canonry-integration-traffic": "0.0.0",
107
106
  "@ainyc/canonry-integration-wordpress": "0.0.0",
108
107
  "@ainyc/canonry-provider-claude": "0.0.0",
109
108
  "@ainyc/canonry-provider-cdp": "0.0.0",
110
- "@ainyc/canonry-intelligence": "0.0.0",
109
+ "@ainyc/canonry-provider-gemini": "0.0.0",
111
110
  "@ainyc/canonry-provider-local": "0.0.0",
111
+ "@ainyc/canonry-intelligence": "0.0.0",
112
112
  "@ainyc/canonry-provider-muse": "0.0.0",
113
113
  "@ainyc/canonry-provider-openai": "0.0.0",
114
- "@ainyc/canonry-provider-gemini": "0.0.0",
115
114
  "@ainyc/canonry-provider-perplexity": "0.0.0",
116
115
  "@ainyc/canonry-integration-typesafe": "0.0.0"
117
116
  },