@canonry/canonry 5.6.0 → 5.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/agent-workspace/skills/aero/SKILL.md +18 -0
- package/assets/agent-workspace/skills/aero/soul.md +2 -0
- package/assets/agent-workspace/skills/canonry/references/canonry-cli.md +5 -4
- package/assets/assets/{AuditHistoryPanel-DVUbjx1M.js → AuditHistoryPanel-DumM4n44.js} +1 -1
- package/assets/assets/{BacklinksPage-D01VTDAp.js → BacklinksPage-DHW-aDYf.js} +1 -1
- package/assets/assets/{HistoryPage-Bk1gsXe5.js → HistoryPage-DJgCpcmY.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-D7p5vpY_.js → MeasurementPropertyPage-CblC7DUV.js} +1 -1
- package/assets/assets/{ProjectPage-Dv3USEIE.js → ProjectPage-BKZyG1S3.js} +1 -1
- package/assets/assets/{RunRow-Dpa0kAip.js → RunRow-plH2LI7o.js} +1 -1
- package/assets/assets/{RunsPage-B59z7DQ_.js → RunsPage-JCSy7P9I.js} +1 -1
- package/assets/assets/{SettingsPage-HJDgmQi9.js → SettingsPage-B8KXT4YK.js} +1 -1
- package/assets/assets/{SiteHealthSection-BnJA-zvQ.js → SiteHealthSection-06pNjngi.js} +3 -3
- package/assets/assets/{TrafficPage-C8na59q_.js → TrafficPage-BYLDNQ1A.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-B2fO8bDc.js → TrafficSourceDetailPage-CxseBpYr.js} +1 -1
- package/assets/assets/{extract-error-message-670MySRM.js → extract-error-message-Dv5fwiqy.js} +1 -1
- package/assets/assets/index-2Ldc0Hq4.js +86 -0
- package/assets/assets/{index-PT4UiPTM.css → index-neNKCg78.css} +1 -1
- package/assets/assets/{react-sigma_core.esm.min-DOhuYLQj.js → react-sigma_core.esm.min-C8381RhL.js} +1 -1
- package/assets/assets/{v2-overview-adapter-CQyDNkXa.js → v2-overview-adapter-BQD1Ap8K.js} +1 -1
- package/assets/assets/vendor-markdown-B4giJcws.js +29 -0
- package/assets/index.html +3 -3
- package/dist/{chunk-TM2NQMJA.js → chunk-5E4ASNU4.js} +54 -7
- package/dist/{chunk-GHAUT7XJ.js → chunk-LR7BVM53.js} +1 -1
- package/dist/{chunk-KZYOJ4F5.js → chunk-R4COV5KR.js} +1 -1
- package/dist/{chunk-I4AHG7K3.js → chunk-S4DBS5DP.js} +1 -1
- package/dist/{chunk-C4KBR4H6.js → chunk-WTYVSCMP.js} +77 -22
- package/dist/cli.js +6 -6
- package/dist/{demo-server-JEGVGOPQ.js → demo-server-WRVVNKLS.js} +2 -2
- package/dist/index.d.ts +20 -8
- package/dist/index.js +4 -4
- package/dist/{intelligence-service-5P62KKG6.js → intelligence-service-4XMMO3JK.js} +1 -1
- package/dist/mcp.js +2 -2
- package/package.json +10 -10
- package/assets/assets/index-DTrkuKOh.js +0 -86
- package/assets/assets/vendor-markdown-B-Oq2NYq.js +0 -14
package/assets/index.html
CHANGED
|
@@ -12,14 +12,14 @@
|
|
|
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-2Ldc0Hq4.js"></script>
|
|
16
16
|
<link rel="modulepreload" crossorigin href="./assets/vendor-tanstack-ZXXkndVj.js">
|
|
17
17
|
<link rel="modulepreload" crossorigin href="./assets/vendor-radix-twS1M3FF.js">
|
|
18
18
|
<link rel="modulepreload" crossorigin href="./assets/vendor-recharts-llkUFBGR.js">
|
|
19
19
|
<link rel="modulepreload" crossorigin href="./assets/vendor-lucide-CneDbhOr.js">
|
|
20
|
-
<link rel="modulepreload" crossorigin href="./assets/vendor-markdown-
|
|
20
|
+
<link rel="modulepreload" crossorigin href="./assets/vendor-markdown-B4giJcws.js">
|
|
21
21
|
<link rel="modulepreload" crossorigin href="./assets/vendor-yaml-GWJz5H2G.js">
|
|
22
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
22
|
+
<link rel="stylesheet" crossorigin href="./assets/index-neNKCg78.css">
|
|
23
23
|
</head>
|
|
24
24
|
<body>
|
|
25
25
|
<div id="root"></div>
|
|
@@ -7406,6 +7406,26 @@ var MIGRATION_VERSIONS = [
|
|
|
7406
7406
|
statements: [
|
|
7407
7407
|
`ALTER TABLE doctor_health_state ADD COLUMN failing_signature TEXT`
|
|
7408
7408
|
]
|
|
7409
|
+
},
|
|
7410
|
+
{
|
|
7411
|
+
version: 158,
|
|
7412
|
+
name: "deepinfra-agent-default-model",
|
|
7413
|
+
// Move the previous agent default once. A later explicit GLM selection
|
|
7414
|
+
// must survive subsequent boots and session hydration.
|
|
7415
|
+
//
|
|
7416
|
+
// A run hook rather than a statement for two reasons. The statement
|
|
7417
|
+
// allowlist is schema-shaped and this rewrites VALUES, and a supported
|
|
7418
|
+
// legacy database can reach this version with no `agent_sessions` at
|
|
7419
|
+
// all: one stamped in `_migrations` at a version above 38 resumes past
|
|
7420
|
+
// the migration that introduces the table, so an unguarded UPDATE dies
|
|
7421
|
+
// with `no such table`.
|
|
7422
|
+
statements: [],
|
|
7423
|
+
run: (tx) => {
|
|
7424
|
+
if (!tableExists(tx, "agent_sessions")) return;
|
|
7425
|
+
tx.run(sql2.raw(
|
|
7426
|
+
`UPDATE agent_sessions SET model_id = 'deepseek-ai/DeepSeek-V4-Flash' WHERE model_provider = 'deepinfra' AND model_id = 'zai-org/GLM-5.2'`
|
|
7427
|
+
));
|
|
7428
|
+
}
|
|
7409
7429
|
}
|
|
7410
7430
|
];
|
|
7411
7431
|
function addRunsMeasurementPlanVersionForeignKey(tx) {
|
|
@@ -11345,6 +11365,22 @@ function requireAdminSession(request) {
|
|
|
11345
11365
|
if (!role || role === UserRoles.admin) return;
|
|
11346
11366
|
throw forbidden(ADMIN_ONLY_MESSAGE);
|
|
11347
11367
|
}
|
|
11368
|
+
var NARROW_KEY_DENIED_MESSAGE = "This API key is narrower than the install, so it cannot use an administrator surface.";
|
|
11369
|
+
function isInstanceAdministrator(request) {
|
|
11370
|
+
const principal = request.principal;
|
|
11371
|
+
if (!principal) return true;
|
|
11372
|
+
const role = principal.kind === "user" ? principal.role : principal.delegatedUser?.role;
|
|
11373
|
+
if (role && role !== UserRoles.admin) return false;
|
|
11374
|
+
return !principal.projectId && principal.scopes.includes(WILDCARD_SCOPE);
|
|
11375
|
+
}
|
|
11376
|
+
function requireInstanceAdministrator(request) {
|
|
11377
|
+
const principal = request.principal;
|
|
11378
|
+
if (!principal) return;
|
|
11379
|
+
const role = principal.kind === "user" ? principal.role : principal.delegatedUser?.role;
|
|
11380
|
+
if (role && role !== UserRoles.admin) throw forbidden(ADMIN_ONLY_MESSAGE);
|
|
11381
|
+
if (isInstanceAdministrator(request)) return;
|
|
11382
|
+
throw forbidden(NARROW_KEY_DENIED_MESSAGE);
|
|
11383
|
+
}
|
|
11348
11384
|
function requireOperator(request) {
|
|
11349
11385
|
const principal = request.principal;
|
|
11350
11386
|
if (request.operatorAccess === true && principal?.kind === "api-key" && !principal.viaCookie && !principal.projectId && !principal.delegatedUser) return;
|
|
@@ -42637,7 +42673,7 @@ var canonryLocalRouteCatalog = [
|
|
|
42637
42673
|
method: "get",
|
|
42638
42674
|
path: "/api/v1/projects/{name}/agent/transcript",
|
|
42639
42675
|
summary: "Get the rolling Aero transcript for this project",
|
|
42640
|
-
description: "Returns the full message history of the project-scoped Aero session plus the persisted model provider/id and last-updated timestamp. Empty messages array when the project has no session yet.",
|
|
42676
|
+
description: "Returns the full message history of the project-scoped Aero session plus the persisted model provider/id and last-updated timestamp. Empty messages array when the project has no session yet. Administrator-only: a signed-in viewer, and any API key narrower than the install (read-only, or scoped to a single project), are refused with 403. There is one Aero session per project, so this is the operator conversation rather than metadata about it.",
|
|
42641
42677
|
tags: ["agent"],
|
|
42642
42678
|
parameters: [nameParameter],
|
|
42643
42679
|
responses: {
|
|
@@ -42650,7 +42686,7 @@ var canonryLocalRouteCatalog = [
|
|
|
42650
42686
|
method: "delete",
|
|
42651
42687
|
path: "/api/v1/projects/{name}/agent/transcript",
|
|
42652
42688
|
summary: "Reset the Aero transcript + queued follow-ups",
|
|
42653
|
-
description: "Evicts any live Agent instance, clears the persisted messages and follow_up_queue. A subsequent prompt starts a fresh session.",
|
|
42689
|
+
description: "Evicts any live Agent instance, clears the persisted messages and follow_up_queue. A subsequent prompt starts a fresh session. Administrator-only: a signed-in viewer, and any API key narrower than the install, are refused with 403.",
|
|
42654
42690
|
tags: ["agent"],
|
|
42655
42691
|
parameters: [nameParameter],
|
|
42656
42692
|
responses: {
|
|
@@ -42663,7 +42699,7 @@ var canonryLocalRouteCatalog = [
|
|
|
42663
42699
|
method: "get",
|
|
42664
42700
|
path: "/api/v1/projects/{name}/agent/memory",
|
|
42665
42701
|
summary: "List durable Aero memory entries for a project",
|
|
42666
|
-
description: "Returns the project-scoped agent_memory rows newest-first. Includes both operator-authored notes (source `user`/`aero`) and LLM-authored compaction summaries (source `compaction`, key prefix `compaction:`). The N most-recent rows are also injected into the system prompt at every new session start.",
|
|
42702
|
+
description: "Returns the project-scoped agent_memory rows newest-first. Includes both operator-authored notes (source `user`/`aero`) and LLM-authored compaction summaries (source `compaction`, key prefix `compaction:`). The N most-recent rows are also injected into the system prompt at every new session start. Administrator-only: a signed-in viewer, and any API key narrower than the install, are refused with 403.",
|
|
42667
42703
|
tags: ["agent"],
|
|
42668
42704
|
parameters: [nameParameter],
|
|
42669
42705
|
responses: {
|
|
@@ -42676,7 +42712,7 @@ var canonryLocalRouteCatalog = [
|
|
|
42676
42712
|
method: "put",
|
|
42677
42713
|
path: "/api/v1/projects/{name}/agent/memory",
|
|
42678
42714
|
summary: "Upsert a durable Aero memory entry",
|
|
42679
|
-
description: "Creates or replaces a project-scoped note (max 2 KB, max 128-char key). Same key replaces the prior value. Keys with the reserved `compaction:` prefix are rejected \u2014 that namespace is owned by transcript compaction.",
|
|
42715
|
+
description: "Creates or replaces a project-scoped note (max 2 KB, max 128-char key). Same key replaces the prior value. Keys with the reserved `compaction:` prefix are rejected \u2014 that namespace is owned by transcript compaction. Administrator-only: a signed-in viewer, and any API key narrower than the install, are refused with 403.",
|
|
42680
42716
|
tags: ["agent"],
|
|
42681
42717
|
parameters: [nameParameter],
|
|
42682
42718
|
requestBody: {
|
|
@@ -42705,7 +42741,7 @@ var canonryLocalRouteCatalog = [
|
|
|
42705
42741
|
method: "delete",
|
|
42706
42742
|
path: "/api/v1/projects/{name}/agent/memory",
|
|
42707
42743
|
summary: "Delete a durable Aero memory entry",
|
|
42708
|
-
description: "Removes a single project-scoped note by key. Returns `status: missing` (non-error) when the key never existed. Keys with the reserved `compaction:` prefix are rejected \u2014 those notes are pruned automatically.",
|
|
42744
|
+
description: "Removes a single project-scoped note by key. Returns `status: missing` (non-error) when the key never existed. Keys with the reserved `compaction:` prefix are rejected \u2014 those notes are pruned automatically. Administrator-only: a signed-in viewer, and any API key narrower than the install, are refused with 403.",
|
|
42709
42745
|
tags: ["agent"],
|
|
42710
42746
|
parameters: [nameParameter],
|
|
42711
42747
|
requestBody: {
|
|
@@ -42733,7 +42769,7 @@ var canonryLocalRouteCatalog = [
|
|
|
42733
42769
|
method: "get",
|
|
42734
42770
|
path: "/api/v1/projects/{name}/agent/providers",
|
|
42735
42771
|
summary: "List the LLM providers Aero can route to",
|
|
42736
|
-
description: "Returns every provider Aero knows about with its default model, whether a usable API key is configured, and where the key resolved from (`config` | `env`). `defaultProvider` is the one Aero auto-picks when a caller omits `provider` on the prompt endpoint. Path is project-scoped for auth symmetry; the response does not vary per project today.",
|
|
42772
|
+
description: "Returns every provider Aero knows about with its default model, whether a usable API key is configured, and where the key resolved from (`config` | `env`). `defaultProvider` is the one Aero auto-picks when a caller omits `provider` on the prompt endpoint. Path is project-scoped for auth symmetry; the response does not vary per project today. Administrator-only: a signed-in viewer, and any API key narrower than the install, are refused with 403, because each entry names a default model and which providers are configured is itself administrator knowledge.",
|
|
42737
42773
|
tags: ["agent"],
|
|
42738
42774
|
parameters: [nameParameter],
|
|
42739
42775
|
responses: {
|
|
@@ -42745,7 +42781,7 @@ var canonryLocalRouteCatalog = [
|
|
|
42745
42781
|
method: "post",
|
|
42746
42782
|
path: "/api/v1/projects/{name}/agent/prompt",
|
|
42747
42783
|
summary: "Send a prompt to Aero and stream events back as SSE",
|
|
42748
|
-
description: 'Posts a prompt into the project\'s Aero session and streams `AgentEvent` frames as `text/event-stream`. Each frame is `data: <JSON>\\n\\n`. The server brackets the stream with `{"type":"stream_open"}` and `{"type":"stream_close"}` control frames; `{"type":"error","message":"..."}` surfaces in-stream failures without collapsing the stream. Returns 409 `AGENT_BUSY` if another turn is already in flight for this project. Body field `scope` accepts "all" | "read-only"; omitted defaults to "read-only" (safe dashboard surface). Body field `profile` accepts "default" | "ads-operator"; omitted keeps the default full Canonry operator surface. The CLI passes "all" to keep write tools available.',
|
|
42784
|
+
description: 'Posts a prompt into the project\'s Aero session and streams `AgentEvent` frames as `text/event-stream`. Each frame is `data: <JSON>\\n\\n`. The server brackets the stream with `{"type":"stream_open"}` and `{"type":"stream_close"}` control frames; `{"type":"error","message":"..."}` surfaces in-stream failures without collapsing the stream. Returns 409 `AGENT_BUSY` if another turn is already in flight for this project. Body field `scope` accepts "all" | "read-only"; omitted defaults to "read-only" (safe dashboard surface). Body field `profile` accepts "default" | "ads-operator"; omitted keeps the default full Canonry operator surface. The CLI passes "all" to keep write tools available. Administrator-only: a signed-in viewer, and any API key narrower than the install, are refused with 403. Tools execute with the install root key, so this route is an operator surface regardless of the scope requested.',
|
|
42749
42785
|
tags: ["agent"],
|
|
42750
42786
|
parameters: [nameParameter],
|
|
42751
42787
|
requestBody: {
|
|
@@ -80704,6 +80740,14 @@ var agentProvidersConfiguredCheck = {
|
|
|
80704
80740
|
scope: CheckScopes.global,
|
|
80705
80741
|
title: "Agent provider keys",
|
|
80706
80742
|
run: (ctx) => {
|
|
80743
|
+
if (ctx.callerIsInstanceAdministrator === false) {
|
|
80744
|
+
return {
|
|
80745
|
+
status: CheckStatuses.skipped,
|
|
80746
|
+
code: "agent-providers.restricted",
|
|
80747
|
+
summary: "Agent provider configuration is visible to administrators only.",
|
|
80748
|
+
remediation: null
|
|
80749
|
+
};
|
|
80750
|
+
}
|
|
80707
80751
|
const summary2 = ctx.getAgentProviderSummary?.();
|
|
80708
80752
|
if (!summary2) {
|
|
80709
80753
|
return {
|
|
@@ -81970,6 +82014,7 @@ async function doctorRoutes(app, opts) {
|
|
|
81970
82014
|
redirectUri,
|
|
81971
82015
|
providerSummary: opts.providerSummary,
|
|
81972
82016
|
getAgentProviderSummary: opts.getAgentProviderSummary,
|
|
82017
|
+
callerIsInstanceAdministrator: isInstanceAdministrator(request),
|
|
81973
82018
|
trafficSourceValidators: opts.trafficSourceValidators,
|
|
81974
82019
|
runtimeStatePaths: opts.runtimeStatePaths,
|
|
81975
82020
|
bundledSkills: opts.bundledSkills,
|
|
@@ -82000,6 +82045,7 @@ async function doctorRoutes(app, opts) {
|
|
|
82000
82045
|
redirectUri,
|
|
82001
82046
|
providerSummary: opts.providerSummary,
|
|
82002
82047
|
getAgentProviderSummary: opts.getAgentProviderSummary,
|
|
82048
|
+
callerIsInstanceAdministrator: isInstanceAdministrator(request),
|
|
82003
82049
|
trafficSourceValidators: opts.trafficSourceValidators,
|
|
82004
82050
|
runtimeStatePaths: opts.runtimeStatePaths,
|
|
82005
82051
|
bundledSkills: opts.bundledSkills,
|
|
@@ -86753,6 +86799,7 @@ export {
|
|
|
86753
86799
|
createUserSession,
|
|
86754
86800
|
resolveUserSession,
|
|
86755
86801
|
createCredentialChecker,
|
|
86802
|
+
requireInstanceAdministrator,
|
|
86756
86803
|
hashApiKey,
|
|
86757
86804
|
registerOAuthRoutes,
|
|
86758
86805
|
registerOAuthAdminRoutes,
|
|
@@ -10041,7 +10041,7 @@ var canonryMcpTools = [
|
|
|
10041
10041
|
defineTool({
|
|
10042
10042
|
name: "canonry_project_overview",
|
|
10043
10043
|
title: "Get project overview (composite)",
|
|
10044
|
-
description: 'One-call summary for "how is project X doing?". Returns independent mention and citation coverage, separate query-level movement for each signal, query-basket comparability with added/removed counts, latest run and health, insights, provider/model breakdowns, competitors, attention items, and recent history. Movement excludes queries not shared by both sweeps. Filterable by location and time window. Prefer this over fanning out to separate tools.',
|
|
10044
|
+
description: 'One-call summary for "how is project X doing?". Returns independent mention and citation coverage, separate query-level movement for each signal, query-basket comparability with added/removed counts, latest run and health, insights, provider/model breakdowns, competitors, attention items, and recent history. Movement excludes queries not shared by both sweeps. Filterable by location and time window. Prefer this over fanning out to separate read tools for the same question. SCOPE LIMIT: this returns nothing about Advanced Measurement: no plan, Targets, Properties, groups, or segments. Its silence is not evidence that a project lacks them. Before stating that a project has no Properties, no Advanced plan, or cannot break out per-Property performance, call canonry_measurement_plan_get to establish the portfolio type, and canonry_measurement_portfolio_summary to rank Properties.',
|
|
10045
10045
|
access: "read",
|
|
10046
10046
|
tier: "core",
|
|
10047
10047
|
inputSchema: z4.object({
|
|
@@ -16,12 +16,12 @@ import {
|
|
|
16
16
|
resolveOperatorApiKeyIds,
|
|
17
17
|
runWithUsageTags,
|
|
18
18
|
saveConfigPatch
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-S4DBS5DP.js";
|
|
20
20
|
import {
|
|
21
21
|
deleteSiteCrawlGraphLayout,
|
|
22
22
|
persistSiteCrawlGraphLayout,
|
|
23
23
|
prepareSiteCrawlGraphLayout
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-R4COV5KR.js";
|
|
25
25
|
import {
|
|
26
26
|
PACKAGE_VERSION
|
|
27
27
|
} from "./chunk-AOJU5LKX.js";
|
|
@@ -152,6 +152,7 @@ import {
|
|
|
152
152
|
refreshAccessToken,
|
|
153
153
|
registerOAuthAdminRoutes,
|
|
154
154
|
registerOAuthRoutes,
|
|
155
|
+
requireInstanceAdministrator,
|
|
155
156
|
researchRunQueries,
|
|
156
157
|
researchRuns,
|
|
157
158
|
resolveDestination,
|
|
@@ -176,7 +177,7 @@ import {
|
|
|
176
177
|
siteLivenessState,
|
|
177
178
|
toAlertView,
|
|
178
179
|
usageCounters
|
|
179
|
-
} from "./chunk-
|
|
180
|
+
} from "./chunk-5E4ASNU4.js";
|
|
180
181
|
import {
|
|
181
182
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
182
183
|
AGENT_NONE,
|
|
@@ -6040,6 +6041,13 @@ function resolveAgentEnabled(env, config) {
|
|
|
6040
6041
|
}
|
|
6041
6042
|
return config.agent?.mode !== "disabled";
|
|
6042
6043
|
}
|
|
6044
|
+
function resolveAgentProactiveEnabled(env, config) {
|
|
6045
|
+
const raw = env.CANONRY_AGENT_PROMPT_ONLY?.trim();
|
|
6046
|
+
if (raw) {
|
|
6047
|
+
return !(raw === "1" || raw.toLowerCase() === "true");
|
|
6048
|
+
}
|
|
6049
|
+
return config.agent?.mode !== "prompt-only";
|
|
6050
|
+
}
|
|
6043
6051
|
|
|
6044
6052
|
// src/places-config.ts
|
|
6045
6053
|
var DEFAULT_TIER = "atmosphere";
|
|
@@ -6468,7 +6476,7 @@ function nonBlank(value) {
|
|
|
6468
6476
|
return trimmed ? trimmed : void 0;
|
|
6469
6477
|
}
|
|
6470
6478
|
function resolveBuildCommit(env = process.env) {
|
|
6471
|
-
const embedded = true ? "
|
|
6479
|
+
const embedded = true ? "3bdf995c7b38b778a35e91dc19377f788cc77204" : void 0;
|
|
6472
6480
|
return nonBlank(embedded) ?? nonBlank(env.CANONRY_COMMIT);
|
|
6473
6481
|
}
|
|
6474
6482
|
function resolveInstanceIdentity(env = process.env) {
|
|
@@ -11762,7 +11770,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
11762
11770
|
return result;
|
|
11763
11771
|
}
|
|
11764
11772
|
async function backfillInsightsCommand(project, opts) {
|
|
11765
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
11773
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-4XMMO3JK.js");
|
|
11766
11774
|
const config = loadConfig();
|
|
11767
11775
|
const db = createClient(config.database);
|
|
11768
11776
|
migrate(db);
|
|
@@ -13656,11 +13664,18 @@ var PROVIDER_MODELS = {
|
|
|
13656
13664
|
[LlmCapabilities.classify]: "glm-5-turbo"
|
|
13657
13665
|
},
|
|
13658
13666
|
[AgentProviderIds.deepinfra]: {
|
|
13659
|
-
// DeepInfra `org/Model` slugs
|
|
13660
|
-
//
|
|
13661
|
-
//
|
|
13662
|
-
//
|
|
13663
|
-
|
|
13667
|
+
// DeepInfra `org/Model` slugs, resolved into a custom openai-completions
|
|
13668
|
+
// model rather than pi-ai's catalog.
|
|
13669
|
+
//
|
|
13670
|
+
// The agent tier is pinned explicitly: the dashboard picker sends a
|
|
13671
|
+
// provider and no model, so whatever sits here is what selecting DeepInfra
|
|
13672
|
+
// pins a session to.
|
|
13673
|
+
//
|
|
13674
|
+
// analyze + classify stay on GLM on purpose. Those tiers suppress the
|
|
13675
|
+
// reasoning trace through GLM's chat-template switch, and that branch
|
|
13676
|
+
// applies only to a model declared `reasoning: true`; moving them to
|
|
13677
|
+
// DeepSeek-V4-Flash (which is not) would quietly stop suppressing anything.
|
|
13678
|
+
[LlmCapabilities.agent]: "deepseek-ai/DeepSeek-V4-Flash",
|
|
13664
13679
|
[LlmCapabilities.analyze]: "zai-org/GLM-5.2",
|
|
13665
13680
|
[LlmCapabilities.classify]: "zai-org/GLM-5.2"
|
|
13666
13681
|
}
|
|
@@ -13718,7 +13733,7 @@ var AGENT_PROVIDERS = {
|
|
|
13718
13733
|
},
|
|
13719
13734
|
// Best-effort metadata. Costs are USD/1M tokens (DeepInfra published
|
|
13720
13735
|
// rates: GLM-5.2 ~$0.95 in / $0.18 cached / $3.00 out; DeepSeek-V4-Flash
|
|
13721
|
-
//
|
|
13736
|
+
// $0.09 in / $0.18 out). contextWindow is DeepInfra's 1M (fp4) serving
|
|
13722
13737
|
// window for both models; it's descriptive (see OpenAiCompatibleModelMeta),
|
|
13723
13738
|
// so it documents the real window rather than gating compaction.
|
|
13724
13739
|
knownModels: {
|
|
@@ -13732,7 +13747,7 @@ var AGENT_PROVIDERS = {
|
|
|
13732
13747
|
contextWindow: 1048576,
|
|
13733
13748
|
maxTokens: 32768,
|
|
13734
13749
|
reasoning: false,
|
|
13735
|
-
cost: { input: 0.
|
|
13750
|
+
cost: { input: 0.09, output: 0.18, cacheRead: 0, cacheWrite: 0 }
|
|
13736
13751
|
}
|
|
13737
13752
|
},
|
|
13738
13753
|
// Fallback for arbitrary `--model` slugs we don't ship as tiers. cost is
|
|
@@ -13981,6 +13996,8 @@ import { Type as Type2 } from "@sinclair/typebox";
|
|
|
13981
13996
|
import { randomUUID } from "crypto";
|
|
13982
13997
|
var MAX_TOOL_RESULT_CHARS = 2e4;
|
|
13983
13998
|
var TRUNCATION_NOTE = "... (truncated \u2014 result too large)";
|
|
13999
|
+
var MAX_STRUCTURED_TRUNCATION_CHARS = 2e6;
|
|
14000
|
+
var MAX_TRUNCATION_PASSES = 32;
|
|
13984
14001
|
function serializeResult(value) {
|
|
13985
14002
|
return JSON.stringify(value, null, 2);
|
|
13986
14003
|
}
|
|
@@ -13998,11 +14015,17 @@ function largestArrayKey(obj) {
|
|
|
13998
14015
|
return best;
|
|
13999
14016
|
}
|
|
14000
14017
|
function trimRowsToFit(rows, render) {
|
|
14001
|
-
|
|
14002
|
-
|
|
14003
|
-
|
|
14004
|
-
|
|
14005
|
-
|
|
14018
|
+
if (rows.length === 0) return [];
|
|
14019
|
+
const all = rows.slice();
|
|
14020
|
+
if (render(all).length <= MAX_TOOL_RESULT_CHARS) return all;
|
|
14021
|
+
let low = 0;
|
|
14022
|
+
let high = rows.length - 1;
|
|
14023
|
+
while (low < high) {
|
|
14024
|
+
const middle = Math.ceil((low + high) / 2);
|
|
14025
|
+
if (render(rows.slice(0, middle)).length <= MAX_TOOL_RESULT_CHARS) low = middle;
|
|
14026
|
+
else high = middle - 1;
|
|
14027
|
+
}
|
|
14028
|
+
return rows.slice(0, low);
|
|
14006
14029
|
}
|
|
14007
14030
|
function nestedArrayCandidates(root) {
|
|
14008
14031
|
const candidates = [];
|
|
@@ -14039,7 +14062,9 @@ function trimNestedArrays(full) {
|
|
|
14039
14062
|
const copy = parsed;
|
|
14040
14063
|
copy.__truncated = true;
|
|
14041
14064
|
let out = serializeResult(copy);
|
|
14065
|
+
let passes = 0;
|
|
14042
14066
|
while (out.length > MAX_TOOL_RESULT_CHARS) {
|
|
14067
|
+
if (++passes > MAX_TRUNCATION_PASSES) return void 0;
|
|
14043
14068
|
const candidate = nestedArrayCandidates(copy).at(0);
|
|
14044
14069
|
if (!candidate) return void 0;
|
|
14045
14070
|
const { owner, key, rows } = candidate;
|
|
@@ -14069,6 +14094,9 @@ function trimNestedArrays(full) {
|
|
|
14069
14094
|
function truncateToolResult(details) {
|
|
14070
14095
|
const full = serializeResult(details);
|
|
14071
14096
|
if (full.length <= MAX_TOOL_RESULT_CHARS) return full;
|
|
14097
|
+
if (full.length > MAX_STRUCTURED_TRUNCATION_CHARS) {
|
|
14098
|
+
return full.slice(0, MAX_TOOL_RESULT_CHARS) + "\n" + TRUNCATION_NOTE;
|
|
14099
|
+
}
|
|
14072
14100
|
if (Array.isArray(details)) {
|
|
14073
14101
|
const kept = trimRowsToFit(
|
|
14074
14102
|
details,
|
|
@@ -15038,6 +15066,15 @@ var MAX_HYDRATE_BYTES = 32 * 1024;
|
|
|
15038
15066
|
function escapeMemoryFragment(value) {
|
|
15039
15067
|
return value.replace(/<(\/?)memory>/gi, "<$1\u200Cmemory>");
|
|
15040
15068
|
}
|
|
15069
|
+
function withoutPersistedToolDetails(messages) {
|
|
15070
|
+
return messages.map((message) => {
|
|
15071
|
+
if (!message || typeof message !== "object") return message;
|
|
15072
|
+
const row = message;
|
|
15073
|
+
if (row.role !== "toolResult" || !("details" in row)) return message;
|
|
15074
|
+
const { details: _omitted, ...rest } = row;
|
|
15075
|
+
return rest;
|
|
15076
|
+
});
|
|
15077
|
+
}
|
|
15041
15078
|
var SessionRegistry = class {
|
|
15042
15079
|
live = /* @__PURE__ */ new Map();
|
|
15043
15080
|
pending = /* @__PURE__ */ new Map();
|
|
@@ -15065,6 +15102,10 @@ var SessionRegistry = class {
|
|
|
15065
15102
|
constructor(opts) {
|
|
15066
15103
|
this.opts = opts;
|
|
15067
15104
|
}
|
|
15105
|
+
/** False only in prompt-only mode; absent means proactive, as it always was. */
|
|
15106
|
+
get proactive() {
|
|
15107
|
+
return this.opts.proactive !== false;
|
|
15108
|
+
}
|
|
15068
15109
|
/**
|
|
15069
15110
|
* Lazily load + cache the injected remote MCP tools. The seam OSS-A exposes:
|
|
15070
15111
|
* `loadExternalMcpTools` connects to each configured server over the frozen
|
|
@@ -15149,7 +15190,7 @@ var SessionRegistry = class {
|
|
|
15149
15190
|
this.scopes.set(projectName, preferences?.toolScope ?? AeroToolScopes.all);
|
|
15150
15191
|
this.profiles.set(projectName, preferences?.toolProfile ?? AeroToolProfiles.default);
|
|
15151
15192
|
this.projectIds.set(projectName, projectId);
|
|
15152
|
-
if (queued.length > 0) {
|
|
15193
|
+
if (queued.length > 0 && this.proactive) {
|
|
15153
15194
|
this.appendPending(projectName, queued);
|
|
15154
15195
|
this.updateRow(projectId, { followUpQueue: "[]" });
|
|
15155
15196
|
}
|
|
@@ -15378,7 +15419,7 @@ ${lines.join("\n")}
|
|
|
15378
15419
|
if (!agent) return;
|
|
15379
15420
|
const projectId = this.resolveProjectId(projectName);
|
|
15380
15421
|
this.updateRow(projectId, {
|
|
15381
|
-
messages: JSON.stringify(agent.state.messages)
|
|
15422
|
+
messages: JSON.stringify(withoutPersistedToolDetails(agent.state.messages))
|
|
15382
15423
|
});
|
|
15383
15424
|
}
|
|
15384
15425
|
/**
|
|
@@ -15395,6 +15436,7 @@ ${lines.join("\n")}
|
|
|
15395
15436
|
* both the in-memory pending and the DB-queue migration produced copies).
|
|
15396
15437
|
*/
|
|
15397
15438
|
queueFollowUp(projectName, message) {
|
|
15439
|
+
if (!this.proactive) return;
|
|
15398
15440
|
if (this.live.has(projectName)) {
|
|
15399
15441
|
this.appendPending(projectName, [message]);
|
|
15400
15442
|
} else {
|
|
@@ -15403,6 +15445,7 @@ ${lines.join("\n")}
|
|
|
15403
15445
|
}
|
|
15404
15446
|
/** Consume (and clear) the pending queue for a project. Caller prompts with the result. */
|
|
15405
15447
|
consumePending(projectName) {
|
|
15448
|
+
if (!this.proactive) return [];
|
|
15406
15449
|
const msgs = this.pending.get(projectName) ?? [];
|
|
15407
15450
|
if (msgs.length === 0) return [];
|
|
15408
15451
|
this.pending.delete(projectName);
|
|
@@ -15422,6 +15465,7 @@ ${lines.join("\n")}
|
|
|
15422
15465
|
* RunCoordinator calls after a run completes to wake Aero unprompted.
|
|
15423
15466
|
*/
|
|
15424
15467
|
async drainNow(projectName) {
|
|
15468
|
+
if (!this.proactive) return;
|
|
15425
15469
|
if (!this.hasPendingWork(projectName)) return;
|
|
15426
15470
|
try {
|
|
15427
15471
|
let agent;
|
|
@@ -15549,7 +15593,7 @@ ${lines.join("\n")}
|
|
|
15549
15593
|
systemPrompt: params.systemPrompt,
|
|
15550
15594
|
modelProvider: params.provider ?? params.modelProvider ?? AgentProviderIds.claude,
|
|
15551
15595
|
modelId: params.modelId ?? "claude-opus-4-7",
|
|
15552
|
-
messages: JSON.stringify(params.messages),
|
|
15596
|
+
messages: JSON.stringify(withoutPersistedToolDetails(params.messages)),
|
|
15553
15597
|
followUpQueue: JSON.stringify(params.followUpQueue),
|
|
15554
15598
|
createdAt: now,
|
|
15555
15599
|
updatedAt: now
|
|
@@ -15786,13 +15830,15 @@ function registerAgentRoutes(app, opts) {
|
|
|
15786
15830
|
app.get(
|
|
15787
15831
|
"/projects/:name/agent/transcript",
|
|
15788
15832
|
async (request) => {
|
|
15833
|
+
requireInstanceAdministrator(request);
|
|
15789
15834
|
const project = resolveProject(opts.db, request.params.name);
|
|
15790
15835
|
const row = opts.db.select().from(agentSessions).where(eq22(agentSessions.projectId, project.id)).get();
|
|
15791
15836
|
if (!row) {
|
|
15792
15837
|
return { messages: [], modelProvider: null, modelId: null, updatedAt: null };
|
|
15793
15838
|
}
|
|
15839
|
+
const messages = parseJsonColumn(row.messages, []);
|
|
15794
15840
|
return {
|
|
15795
|
-
messages
|
|
15841
|
+
messages,
|
|
15796
15842
|
modelProvider: row.modelProvider,
|
|
15797
15843
|
modelId: row.modelId,
|
|
15798
15844
|
updatedAt: row.updatedAt
|
|
@@ -15802,6 +15848,7 @@ function registerAgentRoutes(app, opts) {
|
|
|
15802
15848
|
app.get(
|
|
15803
15849
|
"/projects/:name/agent/providers",
|
|
15804
15850
|
async (request) => {
|
|
15851
|
+
requireInstanceAdministrator(request);
|
|
15805
15852
|
resolveProject(opts.db, request.params.name);
|
|
15806
15853
|
return buildAgentProvidersResponse(opts.sessionRegistry.getConfig());
|
|
15807
15854
|
}
|
|
@@ -15809,6 +15856,7 @@ function registerAgentRoutes(app, opts) {
|
|
|
15809
15856
|
app.delete(
|
|
15810
15857
|
"/projects/:name/agent/transcript",
|
|
15811
15858
|
async (request) => {
|
|
15859
|
+
requireInstanceAdministrator(request);
|
|
15812
15860
|
const project = resolveProject(opts.db, request.params.name);
|
|
15813
15861
|
opts.sessionRegistry.reset(project.name);
|
|
15814
15862
|
opts.db.update(agentSessions).set({ messages: "[]", followUpQueue: "[]", updatedAt: (/* @__PURE__ */ new Date()).toISOString() }).where(eq22(agentSessions.projectId, project.id)).run();
|
|
@@ -15816,6 +15864,7 @@ function registerAgentRoutes(app, opts) {
|
|
|
15816
15864
|
}
|
|
15817
15865
|
);
|
|
15818
15866
|
app.post("/projects/:name/agent/prompt", async (request, reply) => {
|
|
15867
|
+
requireInstanceAdministrator(request);
|
|
15819
15868
|
const project = resolveProject(opts.db, request.params.name);
|
|
15820
15869
|
const body = request.body;
|
|
15821
15870
|
const promptText = (body?.prompt ?? "").trim();
|
|
@@ -15877,6 +15926,7 @@ function registerAgentRoutes(app, opts) {
|
|
|
15877
15926
|
app.get(
|
|
15878
15927
|
"/projects/:name/agent/memory",
|
|
15879
15928
|
async (request) => {
|
|
15929
|
+
requireInstanceAdministrator(request);
|
|
15880
15930
|
const project = resolveProject(opts.db, request.params.name);
|
|
15881
15931
|
return { entries: listMemoryEntries(opts.db, project.id) };
|
|
15882
15932
|
}
|
|
@@ -15884,6 +15934,7 @@ function registerAgentRoutes(app, opts) {
|
|
|
15884
15934
|
app.put(
|
|
15885
15935
|
"/projects/:name/agent/memory",
|
|
15886
15936
|
async (request) => {
|
|
15937
|
+
requireInstanceAdministrator(request);
|
|
15887
15938
|
const project = resolveProject(opts.db, request.params.name);
|
|
15888
15939
|
const parsed = agentMemoryUpsertRequestSchema.safeParse(request.body);
|
|
15889
15940
|
if (!parsed.success) {
|
|
@@ -15910,6 +15961,7 @@ function registerAgentRoutes(app, opts) {
|
|
|
15910
15961
|
app.delete(
|
|
15911
15962
|
"/projects/:name/agent/memory",
|
|
15912
15963
|
async (request) => {
|
|
15964
|
+
requireInstanceAdministrator(request);
|
|
15913
15965
|
const project = resolveProject(opts.db, request.params.name);
|
|
15914
15966
|
const parsed = agentMemoryDeleteRequestSchema.safeParse(request.body);
|
|
15915
15967
|
if (!parsed.success) {
|
|
@@ -17597,10 +17649,12 @@ async function createServer(opts) {
|
|
|
17597
17649
|
skipProbe: true
|
|
17598
17650
|
});
|
|
17599
17651
|
const agentEnabled = resolveAgentEnabled(process.env, opts.config);
|
|
17652
|
+
const agentProactive = resolveAgentProactiveEnabled(process.env, opts.config);
|
|
17600
17653
|
const sessionRegistry = agentEnabled ? new SessionRegistry({
|
|
17601
17654
|
db: opts.db,
|
|
17602
17655
|
client: aeroClient,
|
|
17603
|
-
config: opts.config
|
|
17656
|
+
config: opts.config,
|
|
17657
|
+
proactive: agentProactive
|
|
17604
17658
|
}) : void 0;
|
|
17605
17659
|
const runCoordinator = new RunCoordinator(
|
|
17606
17660
|
opts.db,
|
|
@@ -17609,6 +17663,7 @@ async function createServer(opts) {
|
|
|
17609
17663
|
(runId, projectId, result) => notifier.dispatchInsightWebhooks(runId, projectId, result),
|
|
17610
17664
|
async (ctx) => {
|
|
17611
17665
|
if (!sessionRegistry) return;
|
|
17666
|
+
if (!agentProactive) return;
|
|
17612
17667
|
const project = opts.db.select({ name: projects.name }).from(projects).where(eq25(projects.id, ctx.projectId)).get();
|
|
17613
17668
|
if (!project) return;
|
|
17614
17669
|
let content;
|
package/dist/cli.js
CHANGED
|
@@ -35,11 +35,11 @@ import {
|
|
|
35
35
|
trackCliCommandFinished,
|
|
36
36
|
trackEvent,
|
|
37
37
|
waitForServerRuntimeStartup
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-WTYVSCMP.js";
|
|
39
39
|
import {
|
|
40
40
|
autoSyncSkills,
|
|
41
41
|
formatAutoSyncNotice
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-LR7BVM53.js";
|
|
43
43
|
import {
|
|
44
44
|
CliError,
|
|
45
45
|
EXIT_SYSTEM_ERROR,
|
|
@@ -66,13 +66,13 @@ import {
|
|
|
66
66
|
shouldPrintServeSkillsNudge,
|
|
67
67
|
systemError,
|
|
68
68
|
usageError
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-S4DBS5DP.js";
|
|
70
70
|
import {
|
|
71
71
|
DEFAULT_DEMO_TRUSTED_PROXIES,
|
|
72
72
|
trustedProxiesProblem,
|
|
73
73
|
trustedProxyProblem
|
|
74
74
|
} from "./chunk-RB2F4D3Z.js";
|
|
75
|
-
import "./chunk-
|
|
75
|
+
import "./chunk-R4COV5KR.js";
|
|
76
76
|
import "./chunk-AOJU5LKX.js";
|
|
77
77
|
import {
|
|
78
78
|
CLOUDFLARE_WORKER_BINDINGS,
|
|
@@ -88,7 +88,7 @@ import {
|
|
|
88
88
|
queries,
|
|
89
89
|
renderReportHtml,
|
|
90
90
|
runs
|
|
91
|
-
} from "./chunk-
|
|
91
|
+
} from "./chunk-5E4ASNU4.js";
|
|
92
92
|
import {
|
|
93
93
|
AdsDeliverySnapshotStatuses,
|
|
94
94
|
AdsHistoricalCampaignRollupStatuses,
|
|
@@ -435,7 +435,7 @@ function parseDemoTrustedProxies(values) {
|
|
|
435
435
|
async function demoCommand(options) {
|
|
436
436
|
const { host, port } = parseDemoListenOptions(options);
|
|
437
437
|
const trustProxy = parseDemoTrustedProxies(options.trustProxy);
|
|
438
|
-
const { createDemoServer } = await import("./demo-server-
|
|
438
|
+
const { createDemoServer } = await import("./demo-server-WRVVNKLS.js");
|
|
439
439
|
const app = await createDemoServer({ trustProxy });
|
|
440
440
|
let stopping = false;
|
|
441
441
|
const stop = () => {
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
import {
|
|
5
5
|
layoutSiteCrawlGraphInput,
|
|
6
6
|
persistSiteCrawlGraphLayout
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-R4COV5KR.js";
|
|
8
8
|
import {
|
|
9
9
|
PACKAGE_VERSION
|
|
10
10
|
} from "./chunk-AOJU5LKX.js";
|
|
@@ -83,7 +83,7 @@ import {
|
|
|
83
83
|
siteCrawlPages,
|
|
84
84
|
siteCrawlSnapshots,
|
|
85
85
|
trafficSources
|
|
86
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-5E4ASNU4.js";
|
|
87
87
|
import {
|
|
88
88
|
RunKinds,
|
|
89
89
|
SiteCrawlFetchStates,
|
package/dist/index.d.ts
CHANGED
|
@@ -268,15 +268,27 @@ interface ExternalMcpServerConfig {
|
|
|
268
268
|
}
|
|
269
269
|
interface AgentConfigEntry {
|
|
270
270
|
/**
|
|
271
|
-
* Agent mode.
|
|
272
|
-
*
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
* the
|
|
277
|
-
* agent
|
|
271
|
+
* Agent mode. Three states, held on ONE field so they stay mutually
|
|
272
|
+
* exclusive: there is no way to write down "off, but still waking itself".
|
|
273
|
+
*
|
|
274
|
+
* - `'disabled'` turns the built-in Aero agent OFF entirely — the proactive
|
|
275
|
+
* auto-wake on run completion does not fire, the `SessionRegistry` is not
|
|
276
|
+
* constructed, and the interactive agent routes (`/projects/:name/agent/*`)
|
|
277
|
+
* plus the `canonry agent ask` CLI (a thin client of those routes) are not
|
|
278
|
+
* served. Resolved, with the `CANONRY_AGENT_DISABLED` env override, by
|
|
279
|
+
* `resolveAgentEnabled`.
|
|
280
|
+
* - `'prompt-only'` keeps every interactive surface and removes ONLY the
|
|
281
|
+
* proactive wake: Aero answers when asked and never starts a turn by
|
|
282
|
+
* itself, so it costs nothing while nobody is talking to it and never
|
|
283
|
+
* writes into the transcript unattended. Resolved, with the
|
|
284
|
+
* `CANONRY_AGENT_PROMPT_ONLY` env override, by
|
|
285
|
+
* `resolveAgentProactiveEnabled`.
|
|
286
|
+
* - absent (the default) leaves Aero enabled AND proactive, which is the
|
|
287
|
+
* behaviour every existing install already has.
|
|
288
|
+
*
|
|
289
|
+
* Both resolvers live in agent-config.ts.
|
|
278
290
|
*/
|
|
279
|
-
mode?: 'disabled';
|
|
291
|
+
mode?: 'disabled' | 'prompt-only';
|
|
280
292
|
}
|
|
281
293
|
interface DashboardConfigEntry {
|
|
282
294
|
/**
|
package/dist/index.js
CHANGED
|
@@ -3,13 +3,13 @@ import {
|
|
|
3
3
|
createGoogleMarketingCredentialStore,
|
|
4
4
|
createGoogleMarketingRuntime,
|
|
5
5
|
createServer
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-WTYVSCMP.js";
|
|
7
7
|
import {
|
|
8
8
|
loadConfig
|
|
9
|
-
} from "./chunk-
|
|
10
|
-
import "./chunk-
|
|
9
|
+
} from "./chunk-S4DBS5DP.js";
|
|
10
|
+
import "./chunk-R4COV5KR.js";
|
|
11
11
|
import "./chunk-AOJU5LKX.js";
|
|
12
|
-
import "./chunk-
|
|
12
|
+
import "./chunk-5E4ASNU4.js";
|
|
13
13
|
import "./chunk-D3DKDTXP.js";
|
|
14
14
|
export {
|
|
15
15
|
GoogleMarketingRuntimeError,
|