@canonry/canonry 7.46.1 → 7.47.1
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/{AuditHistoryPanel-u65pF2eT.js → AuditHistoryPanel-BTlvVW6p.js} +1 -1
- package/assets/assets/{BacklinksPage-CmYpSNGB.js → BacklinksPage-DQu_3poO.js} +1 -1
- package/assets/assets/{HistoryPage-CqzQSAil.js → HistoryPage-D_3qu4SQ.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-KfpmUisb.js → MeasurementPropertyPage-FKmEMw_G.js} +1 -1
- package/assets/assets/{ProjectPage-BCiospUp.js → ProjectPage-H7nsLkhG.js} +1 -1
- package/assets/assets/{RunsPage-CzPvTnwG.js → RunsPage-CE5wFNdP.js} +1 -1
- package/assets/assets/{SettingsPage-CZYckyPO.js → SettingsPage-D2zKpqOv.js} +1 -1
- package/assets/assets/{SiteHealthSection-Bm5nWAoZ.js → SiteHealthSection-ClZRxJ-A.js} +3 -3
- package/assets/assets/{TrafficPage-DZw_GvaO.js → TrafficPage-BDH4Dzk0.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-CD20PJ4A.js → TrafficSourceDetailPage-DaVUcHXu.js} +1 -1
- package/assets/assets/{extract-error-message-Cpzj_AMZ.js → extract-error-message-YXzyZAEc.js} +1 -1
- package/assets/assets/{index-BHLYJHa-.js → index-Zj8hd7aE.js} +3 -3
- package/assets/assets/{react-sigma_core.esm.min-CK2U3T7S.js → react-sigma_core.esm.min-9j5NHFWR.js} +1 -1
- package/assets/assets/{v2-overview-adapter-DL1IsAM2.js → v2-overview-adapter-BsKpkQvx.js} +1 -1
- package/assets/index.html +1 -1
- package/dist/{chunk-Y2QMWZT7.js → chunk-66K6U5H5.js} +3 -3
- package/dist/{chunk-WMG365JI.js → chunk-CIYCCA2I.js} +11 -2
- package/dist/{chunk-QBZPKXFW.js → chunk-DGKSQ5QD.js} +1 -1
- package/dist/{chunk-GWRIZSIL.js → chunk-HQS2Y7HO.js} +3 -3
- package/dist/{chunk-OO64BWNB.js → chunk-IYAUKA7Z.js} +251 -222
- package/dist/{chunk-QWLKYIQ4.js → chunk-JNBPNW7P.js} +2 -2
- package/dist/{chunk-IBRZ23VQ.js → chunk-QNXQHHCP.js} +36 -13
- package/dist/{chunk-V4TITINC.js → chunk-QS262E4F.js} +9 -1
- package/dist/{chunk-7R2HFAG4.js → chunk-XCS3JXN2.js} +9 -9
- package/dist/{chunk-PCZXWOYX.js → chunk-XHRJYIJQ.js} +1 -1
- package/dist/{cli-catalog-TFCCKIE4.js → cli-catalog-MRYQK7LI.js} +3 -3
- package/dist/cli-commands-ZX7GLZZT.js +15 -0
- package/dist/cli.js +10 -10
- package/dist/{demo-server-5TX4MJIS.js → demo-server-GPNX3EXT.js} +4 -4
- package/dist/index.d.ts +12 -0
- package/dist/index.js +6 -6
- package/dist/{intelligence-service-5BYJSFLW.js → intelligence-service-LZ3MC6G6.js} +2 -2
- package/dist/mcp.js +4 -4
- package/package.json +13 -13
- package/dist/cli-commands-JEN27DWN.js +0 -15
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AGENT_REASONING_LEVELS,
|
|
2
3
|
ApiClient,
|
|
3
4
|
CANONRY_MCP_TIERS,
|
|
4
5
|
CANONRY_MCP_TOOLKITS,
|
|
@@ -21,19 +22,19 @@ import {
|
|
|
21
22
|
saveConfig,
|
|
22
23
|
saveConfigPatch,
|
|
23
24
|
sentimentInstallReadiness
|
|
24
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-CIYCCA2I.js";
|
|
25
26
|
import {
|
|
26
27
|
computeFactorAverages,
|
|
27
28
|
deleteSiteCrawlGraphLayout,
|
|
28
29
|
persistSiteCrawlGraphLayout,
|
|
29
30
|
prepareSiteCrawlGraphLayout,
|
|
30
31
|
recordedSharePct
|
|
31
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-JNBPNW7P.js";
|
|
32
33
|
import {
|
|
33
34
|
CanonryMcpToolNames,
|
|
34
35
|
PACKAGE_VERSION,
|
|
35
36
|
canonryMcpTools
|
|
36
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-XHRJYIJQ.js";
|
|
37
38
|
import {
|
|
38
39
|
CliError
|
|
39
40
|
} from "./chunk-HGMYEDAQ.js";
|
|
@@ -240,7 +241,7 @@ import {
|
|
|
240
241
|
webhookResponseReason,
|
|
241
242
|
webhookTargetRefusalReason,
|
|
242
243
|
writeAuditLog
|
|
243
|
-
} from "./chunk-
|
|
244
|
+
} from "./chunk-QNXQHHCP.js";
|
|
244
245
|
import {
|
|
245
246
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
246
247
|
AGENT_NONE,
|
|
@@ -488,7 +489,7 @@ import {
|
|
|
488
489
|
winnabilityClassLabel,
|
|
489
490
|
withRetry,
|
|
490
491
|
withSkippedProviders
|
|
491
|
-
} from "./chunk-
|
|
492
|
+
} from "./chunk-QS262E4F.js";
|
|
492
493
|
|
|
493
494
|
// src/runtime-context.ts
|
|
494
495
|
function cliRuntimeContext(env = process.env, stdio = process) {
|
|
@@ -3586,16 +3587,14 @@ var DefaultGoogleMarketingRuntime = class {
|
|
|
3586
3587
|
"INVALID_INPUT"
|
|
3587
3588
|
);
|
|
3588
3589
|
}
|
|
3589
|
-
const
|
|
3590
|
-
|
|
3591
|
-
throw new GoogleMarketingRuntimeError("Selected GTM workspace was not found", "RESOURCE_NOT_FOUND");
|
|
3592
|
-
}
|
|
3590
|
+
const selectedWorkspaceExists = selectedWorkspaceId !== null && workspaceDtos.some((candidate) => candidate.id === selectedWorkspaceId);
|
|
3591
|
+
const workspaceId = selectedWorkspaceId === null || selectedWorkspaceExists ? selectedWorkspaceId : workspaceDtos.length === 1 ? workspaceDtos[0].id : null;
|
|
3593
3592
|
const snapshotReads = [
|
|
3594
3593
|
client.getLiveSnapshot(selectedContainerPath)
|
|
3595
3594
|
];
|
|
3596
|
-
if (
|
|
3595
|
+
if (workspaceId) {
|
|
3597
3596
|
snapshotReads.push(client.getWorkspaceSnapshot(
|
|
3598
|
-
workspacePath(selectedAccountId, selectedContainerId,
|
|
3597
|
+
workspacePath(selectedAccountId, selectedContainerId, workspaceId)
|
|
3599
3598
|
));
|
|
3600
3599
|
}
|
|
3601
3600
|
const snapshots = await Promise.all(snapshotReads);
|
|
@@ -3624,7 +3623,7 @@ var DefaultGoogleMarketingRuntime = class {
|
|
|
3624
3623
|
payload,
|
|
3625
3624
|
selectedAccountId,
|
|
3626
3625
|
selectedContainerId,
|
|
3627
|
-
|
|
3626
|
+
workspaceId,
|
|
3628
3627
|
raw,
|
|
3629
3628
|
capturedAt
|
|
3630
3629
|
);
|
|
@@ -3714,7 +3713,7 @@ import path10 from "path";
|
|
|
3714
3713
|
import { isIP } from "net";
|
|
3715
3714
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
3716
3715
|
import { setImmediate as yieldToEventLoop4 } from "timers/promises";
|
|
3717
|
-
import { and as and25, eq as eq31, isNotNull as isNotNull5, isNull as isNull5, lte as lte2, max, ne as ne4, or as or3, sql as
|
|
3716
|
+
import { and as and25, eq as eq31, isNotNull as isNotNull5, isNull as isNull5, lte as lte2, max, ne as ne4, or as or3, sql as sql13 } from "drizzle-orm";
|
|
3718
3717
|
|
|
3719
3718
|
// ../integration-typesafe/src/classifier.ts
|
|
3720
3719
|
import { createHash } from "crypto";
|
|
@@ -7898,6 +7897,216 @@ function resolveEmbedConfig(env, config) {
|
|
|
7898
7897
|
};
|
|
7899
7898
|
}
|
|
7900
7899
|
|
|
7900
|
+
// src/agent/providers.ts
|
|
7901
|
+
import "@earendil-works/pi-ai";
|
|
7902
|
+
|
|
7903
|
+
// src/agent/pi-models.ts
|
|
7904
|
+
import "@earendil-works/pi-ai";
|
|
7905
|
+
import { builtinModels } from "@earendil-works/pi-ai/providers/all";
|
|
7906
|
+
var aeroModels = builtinModels();
|
|
7907
|
+
var DEFAULT_MAX_RETRIES = 2;
|
|
7908
|
+
var DEFAULT_MAX_OUTPUT_TOKENS = 32e3;
|
|
7909
|
+
var CANONRY_USER_AGENT = "canonry";
|
|
7910
|
+
var STAINLESS_HOST_HEADERS = {
|
|
7911
|
+
"X-Stainless-OS": null,
|
|
7912
|
+
"X-Stainless-Arch": null,
|
|
7913
|
+
"X-Stainless-Runtime-Version": null
|
|
7914
|
+
};
|
|
7915
|
+
var HOST_HEADERS = {
|
|
7916
|
+
"anthropic-messages": STAINLESS_HOST_HEADERS,
|
|
7917
|
+
"openai-responses": STAINLESS_HOST_HEADERS,
|
|
7918
|
+
"openai-completions": STAINLESS_HOST_HEADERS,
|
|
7919
|
+
"google-generative-ai": { "x-goog-api-client": CANONRY_USER_AGENT }
|
|
7920
|
+
};
|
|
7921
|
+
function outputCap(model) {
|
|
7922
|
+
return Math.min(model.maxTokens, DEFAULT_MAX_OUTPUT_TOKENS);
|
|
7923
|
+
}
|
|
7924
|
+
function canonryDefaults(model, options) {
|
|
7925
|
+
return {
|
|
7926
|
+
...options,
|
|
7927
|
+
maxRetries: options?.maxRetries ?? DEFAULT_MAX_RETRIES,
|
|
7928
|
+
maxTokens: options?.maxTokens ?? outputCap(model),
|
|
7929
|
+
headers: { "User-Agent": CANONRY_USER_AGENT, ...HOST_HEADERS[model.api], ...options?.headers }
|
|
7930
|
+
};
|
|
7931
|
+
}
|
|
7932
|
+
var aeroStreamFn = (model, context, options) => aeroModels.streamSimple(model, context, canonryDefaults(model, options));
|
|
7933
|
+
function completeOnce(model, context, options = {}) {
|
|
7934
|
+
return aeroModels.complete(model, context, canonryDefaults(model, options));
|
|
7935
|
+
}
|
|
7936
|
+
|
|
7937
|
+
// src/agent/providers.ts
|
|
7938
|
+
var PROVIDER_MODELS = {
|
|
7939
|
+
[AgentProviderIds.claude]: {
|
|
7940
|
+
[LlmCapabilities.agent]: "claude-opus-4-7",
|
|
7941
|
+
[LlmCapabilities.analyze]: "claude-sonnet-4-6",
|
|
7942
|
+
[LlmCapabilities.classify]: "claude-haiku-4-5"
|
|
7943
|
+
},
|
|
7944
|
+
[AgentProviderIds.openai]: {
|
|
7945
|
+
[LlmCapabilities.agent]: "gpt-5.1",
|
|
7946
|
+
[LlmCapabilities.analyze]: "gpt-5-mini",
|
|
7947
|
+
[LlmCapabilities.classify]: "gpt-5-nano"
|
|
7948
|
+
},
|
|
7949
|
+
[AgentProviderIds.gemini]: {
|
|
7950
|
+
// Gemini's Flash is already cheap + capable; Flash-Lite is the
|
|
7951
|
+
// dedicated micro tier for classify. Analyze stays on flash because
|
|
7952
|
+
// flash-lite drops too much quality for structured synthesis.
|
|
7953
|
+
// Exact IDs, never Google's `-latest` aliases: pi-ai derives request
|
|
7954
|
+
// options (thinking level) from the catalog entry for the ID it is given,
|
|
7955
|
+
// and an alias entry can lag the model it serves. `gemini-flash-latest`
|
|
7956
|
+
// allows MINIMAL thinking while the 3.8 Flash it resolves to rejects it,
|
|
7957
|
+
// so every Aero turn failed. Sweeps can use the alias; Aero cannot.
|
|
7958
|
+
[LlmCapabilities.agent]: "gemini-3.8-flash",
|
|
7959
|
+
[LlmCapabilities.analyze]: "gemini-3.8-flash",
|
|
7960
|
+
[LlmCapabilities.classify]: "gemini-3.5-flash-lite"
|
|
7961
|
+
},
|
|
7962
|
+
[AgentProviderIds.zai]: {
|
|
7963
|
+
// GLM lineage: 5.2 replaced 5.1, which pi-ai 0.87 dropped from its
|
|
7964
|
+
// catalog; 5-turbo is the cheaper tier good for structured tasks and
|
|
7965
|
+
// classification.
|
|
7966
|
+
[LlmCapabilities.agent]: "glm-5.2",
|
|
7967
|
+
[LlmCapabilities.analyze]: "glm-5-turbo",
|
|
7968
|
+
[LlmCapabilities.classify]: "glm-5-turbo"
|
|
7969
|
+
}
|
|
7970
|
+
};
|
|
7971
|
+
var PROVIDER_DEFAULT_REASONING = {
|
|
7972
|
+
[AgentProviderIds.claude]: "off",
|
|
7973
|
+
[AgentProviderIds.openai]: "low",
|
|
7974
|
+
[AgentProviderIds.gemini]: "off",
|
|
7975
|
+
[AgentProviderIds.zai]: "off"
|
|
7976
|
+
};
|
|
7977
|
+
var AGENT_PROVIDERS = {
|
|
7978
|
+
[AgentProviderIds.claude]: {
|
|
7979
|
+
piAiProvider: "anthropic",
|
|
7980
|
+
label: "Anthropic (Claude)",
|
|
7981
|
+
defaultModel: PROVIDER_MODELS[AgentProviderIds.claude][LlmCapabilities.agent],
|
|
7982
|
+
autoDetectPriority: 0
|
|
7983
|
+
},
|
|
7984
|
+
[AgentProviderIds.openai]: {
|
|
7985
|
+
piAiProvider: "openai",
|
|
7986
|
+
label: "OpenAI",
|
|
7987
|
+
defaultModel: PROVIDER_MODELS[AgentProviderIds.openai][LlmCapabilities.agent],
|
|
7988
|
+
autoDetectPriority: 1
|
|
7989
|
+
},
|
|
7990
|
+
[AgentProviderIds.gemini]: {
|
|
7991
|
+
piAiProvider: "google",
|
|
7992
|
+
label: "Google (Gemini)",
|
|
7993
|
+
defaultModel: PROVIDER_MODELS[AgentProviderIds.gemini][LlmCapabilities.agent],
|
|
7994
|
+
autoDetectPriority: 2
|
|
7995
|
+
},
|
|
7996
|
+
[AgentProviderIds.zai]: {
|
|
7997
|
+
piAiProvider: "zai",
|
|
7998
|
+
label: "Z.ai (GLM)",
|
|
7999
|
+
defaultModel: PROVIDER_MODELS[AgentProviderIds.zai][LlmCapabilities.agent],
|
|
8000
|
+
autoDetectPriority: 3
|
|
8001
|
+
}
|
|
8002
|
+
};
|
|
8003
|
+
function agentProvidersByPriority() {
|
|
8004
|
+
return Object.keys(AGENT_PROVIDERS).slice().sort((a, b) => AGENT_PROVIDERS[a].autoDetectPriority - AGENT_PROVIDERS[b].autoDetectPriority);
|
|
8005
|
+
}
|
|
8006
|
+
function listAgentProviders() {
|
|
8007
|
+
return AGENT_PROVIDER_IDS;
|
|
8008
|
+
}
|
|
8009
|
+
function getAgentProvider(name) {
|
|
8010
|
+
return AGENT_PROVIDERS[name];
|
|
8011
|
+
}
|
|
8012
|
+
function coerceAgentProvider(value) {
|
|
8013
|
+
if (!value) return void 0;
|
|
8014
|
+
return isAgentProviderId(value) ? value : void 0;
|
|
8015
|
+
}
|
|
8016
|
+
function resolveModelForProvider(provider, modelId) {
|
|
8017
|
+
return resolveModelForCapability(provider, LlmCapabilities.agent, modelId);
|
|
8018
|
+
}
|
|
8019
|
+
function resolveModelForCapability(provider, capability, modelIdOverride) {
|
|
8020
|
+
const entry = AGENT_PROVIDERS[provider];
|
|
8021
|
+
const id = modelIdOverride ?? PROVIDER_MODELS[provider][capability];
|
|
8022
|
+
const model = aeroModels.getModel(entry.piAiProvider, id);
|
|
8023
|
+
if (!model) {
|
|
8024
|
+
throw new Error(
|
|
8025
|
+
`Model '${id}' not found for pi-ai provider '${entry.piAiProvider}'. Verify PROVIDER_MODELS[${provider}][${capability}] against the installed @earendil-works/pi-ai catalog.`
|
|
8026
|
+
);
|
|
8027
|
+
}
|
|
8028
|
+
if (provider === AgentProviderIds.gemini && process.env.GEMINI_BASE_URL) {
|
|
8029
|
+
const base = process.env.GEMINI_BASE_URL.replace(/\/+$/, "");
|
|
8030
|
+
const baseUrl = base.endsWith("/v1beta") ? base : `${base}/v1beta`;
|
|
8031
|
+
return { ...model, baseUrl };
|
|
8032
|
+
}
|
|
8033
|
+
if (provider === AgentProviderIds.zai && process.env.ZAI_BASE_URL) {
|
|
8034
|
+
const baseUrl = process.env.ZAI_BASE_URL.replace(/\/+$/, "");
|
|
8035
|
+
return { ...model, baseUrl };
|
|
8036
|
+
}
|
|
8037
|
+
return model;
|
|
8038
|
+
}
|
|
8039
|
+
function isAgentModelAvailable(provider, id) {
|
|
8040
|
+
return !!aeroModels.getModel(AGENT_PROVIDERS[provider].piAiProvider, id);
|
|
8041
|
+
}
|
|
8042
|
+
function validateAgentProviderRegistry() {
|
|
8043
|
+
for (const provider of listAgentProviders()) {
|
|
8044
|
+
for (const capability of LLM_CAPABILITIES) {
|
|
8045
|
+
resolveModelForCapability(provider, capability);
|
|
8046
|
+
}
|
|
8047
|
+
const entry = AGENT_PROVIDERS[provider];
|
|
8048
|
+
const agentModel = PROVIDER_MODELS[provider][LlmCapabilities.agent];
|
|
8049
|
+
if (entry.defaultModel !== agentModel) {
|
|
8050
|
+
throw new Error(
|
|
8051
|
+
`AGENT_PROVIDERS[${provider}].defaultModel ('${entry.defaultModel}') does not match PROVIDER_MODELS[${provider}].agent ('${agentModel}'). The two must stay in sync \u2014 defaultModel is a backward-compat shortcut to the agent-tier model.`
|
|
8052
|
+
);
|
|
8053
|
+
}
|
|
8054
|
+
}
|
|
8055
|
+
}
|
|
8056
|
+
function resolveApiKeyFor(providerOrPiAi, config) {
|
|
8057
|
+
return resolveApiKeySource(providerOrPiAi, config)?.key;
|
|
8058
|
+
}
|
|
8059
|
+
function resolveApiKeySource(providerOrPiAi, config) {
|
|
8060
|
+
const id = resolveAgentId(providerOrPiAi);
|
|
8061
|
+
if (!id) return void 0;
|
|
8062
|
+
const fromConfig = config.providers?.[id]?.apiKey;
|
|
8063
|
+
if (fromConfig) return { key: fromConfig, source: "config" };
|
|
8064
|
+
const fromEnv = agentProviderApiKeyEnvVars(id).map((name) => process.env[name]).find((value) => !!value);
|
|
8065
|
+
if (fromEnv) return { key: fromEnv, source: "env" };
|
|
8066
|
+
return void 0;
|
|
8067
|
+
}
|
|
8068
|
+
var CATALOG_API_KEY_ENV_VARS = {
|
|
8069
|
+
anthropic: ["ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_API_KEY"],
|
|
8070
|
+
openai: ["OPENAI_API_KEY"],
|
|
8071
|
+
google: ["GEMINI_API_KEY"],
|
|
8072
|
+
zai: ["ZAI_API_KEY"]
|
|
8073
|
+
};
|
|
8074
|
+
function agentProviderApiKeyEnvVars(id) {
|
|
8075
|
+
const entry = AGENT_PROVIDERS[id];
|
|
8076
|
+
return CATALOG_API_KEY_ENV_VARS[entry.piAiProvider] ?? [`${entry.piAiProvider.toUpperCase()}_API_KEY`];
|
|
8077
|
+
}
|
|
8078
|
+
function agentProviderApiKeyEnvVar(id) {
|
|
8079
|
+
const names = agentProviderApiKeyEnvVars(id);
|
|
8080
|
+
return names[names.length - 1];
|
|
8081
|
+
}
|
|
8082
|
+
function resolveAgentId(providerOrPiAi) {
|
|
8083
|
+
if (isAgentProviderId(providerOrPiAi)) return providerOrPiAi;
|
|
8084
|
+
for (const id of AGENT_PROVIDER_IDS) {
|
|
8085
|
+
if (AGENT_PROVIDERS[id].piAiProvider === providerOrPiAi) return id;
|
|
8086
|
+
}
|
|
8087
|
+
return void 0;
|
|
8088
|
+
}
|
|
8089
|
+
function buildAgentProvidersResponse(config) {
|
|
8090
|
+
const pinned = coerceAgentProvider(config.agent?.provider ?? void 0);
|
|
8091
|
+
const pinnedModel = pinned ? config.agent?.model ?? void 0 : void 0;
|
|
8092
|
+
const providers = listAgentProviders().map((id) => {
|
|
8093
|
+
const entry = AGENT_PROVIDERS[id];
|
|
8094
|
+
const source = resolveApiKeySource(id, config);
|
|
8095
|
+
return {
|
|
8096
|
+
id,
|
|
8097
|
+
label: entry.label,
|
|
8098
|
+
defaultModel: id === pinned && pinnedModel ? pinnedModel : entry.defaultModel,
|
|
8099
|
+
configured: source !== void 0,
|
|
8100
|
+
keySource: source?.source ?? null
|
|
8101
|
+
};
|
|
8102
|
+
});
|
|
8103
|
+
const firstConfigured = agentProvidersByPriority().find((p) => resolveApiKeySource(p, config));
|
|
8104
|
+
return {
|
|
8105
|
+
providers,
|
|
8106
|
+
defaultProvider: pinned ?? firstConfigured ?? null
|
|
8107
|
+
};
|
|
8108
|
+
}
|
|
8109
|
+
|
|
7901
8110
|
// src/agent-config.ts
|
|
7902
8111
|
function resolveAgentEnabled(env, config) {
|
|
7903
8112
|
const raw = env.CANONRY_AGENT_DISABLED?.trim();
|
|
@@ -7918,6 +8127,11 @@ function resolveAgentAllowViewers(env, config) {
|
|
|
7918
8127
|
if (raw) return raw === "1" || raw.toLowerCase() === "true";
|
|
7919
8128
|
return config.agent?.allowViewers === true;
|
|
7920
8129
|
}
|
|
8130
|
+
function resolveAgentReasoning(env, config, provider) {
|
|
8131
|
+
const raw = env.CANONRY_AGENT_REASONING?.trim().toLowerCase();
|
|
8132
|
+
if (raw && AGENT_REASONING_LEVELS.includes(raw)) return raw;
|
|
8133
|
+
return config.agent?.reasoning ?? PROVIDER_DEFAULT_REASONING[provider];
|
|
8134
|
+
}
|
|
7921
8135
|
|
|
7922
8136
|
// src/places-config.ts
|
|
7923
8137
|
var DEFAULT_TIER = "atmosphere";
|
|
@@ -8379,7 +8593,7 @@ function nonBlank(value) {
|
|
|
8379
8593
|
return trimmed ? trimmed : void 0;
|
|
8380
8594
|
}
|
|
8381
8595
|
function resolveBuildCommit(env = process.env) {
|
|
8382
|
-
const embedded = true ? "
|
|
8596
|
+
const embedded = true ? "6f65fc00d407b63da0801a4f151064d5f7065440" : void 0;
|
|
8383
8597
|
return nonBlank(embedded) ?? nonBlank(env.CANONRY_COMMIT);
|
|
8384
8598
|
}
|
|
8385
8599
|
function resolveInstanceIdentity(env = process.env) {
|
|
@@ -15433,210 +15647,6 @@ function recordLlmUsageEvent(args) {
|
|
|
15433
15647
|
}
|
|
15434
15648
|
}
|
|
15435
15649
|
|
|
15436
|
-
// src/agent/providers.ts
|
|
15437
|
-
import "@earendil-works/pi-ai";
|
|
15438
|
-
|
|
15439
|
-
// src/agent/pi-models.ts
|
|
15440
|
-
import "@earendil-works/pi-ai";
|
|
15441
|
-
import { builtinModels } from "@earendil-works/pi-ai/providers/all";
|
|
15442
|
-
var aeroModels = builtinModels();
|
|
15443
|
-
var DEFAULT_MAX_RETRIES = 2;
|
|
15444
|
-
var DEFAULT_MAX_OUTPUT_TOKENS = 32e3;
|
|
15445
|
-
var CANONRY_USER_AGENT = "canonry";
|
|
15446
|
-
var STAINLESS_HOST_HEADERS = {
|
|
15447
|
-
"X-Stainless-OS": null,
|
|
15448
|
-
"X-Stainless-Arch": null,
|
|
15449
|
-
"X-Stainless-Runtime-Version": null
|
|
15450
|
-
};
|
|
15451
|
-
var HOST_HEADERS = {
|
|
15452
|
-
"anthropic-messages": STAINLESS_HOST_HEADERS,
|
|
15453
|
-
"openai-responses": STAINLESS_HOST_HEADERS,
|
|
15454
|
-
"openai-completions": STAINLESS_HOST_HEADERS,
|
|
15455
|
-
"google-generative-ai": { "x-goog-api-client": CANONRY_USER_AGENT }
|
|
15456
|
-
};
|
|
15457
|
-
function outputCap(model) {
|
|
15458
|
-
return Math.min(model.maxTokens, DEFAULT_MAX_OUTPUT_TOKENS);
|
|
15459
|
-
}
|
|
15460
|
-
function canonryDefaults(model, options) {
|
|
15461
|
-
return {
|
|
15462
|
-
...options,
|
|
15463
|
-
maxRetries: options?.maxRetries ?? DEFAULT_MAX_RETRIES,
|
|
15464
|
-
maxTokens: options?.maxTokens ?? outputCap(model),
|
|
15465
|
-
headers: { "User-Agent": CANONRY_USER_AGENT, ...HOST_HEADERS[model.api], ...options?.headers }
|
|
15466
|
-
};
|
|
15467
|
-
}
|
|
15468
|
-
var aeroStreamFn = (model, context, options) => aeroModels.streamSimple(model, context, canonryDefaults(model, options));
|
|
15469
|
-
function completeOnce(model, context, options = {}) {
|
|
15470
|
-
return aeroModels.complete(model, context, canonryDefaults(model, options));
|
|
15471
|
-
}
|
|
15472
|
-
|
|
15473
|
-
// src/agent/providers.ts
|
|
15474
|
-
var PROVIDER_MODELS = {
|
|
15475
|
-
[AgentProviderIds.claude]: {
|
|
15476
|
-
[LlmCapabilities.agent]: "claude-opus-4-7",
|
|
15477
|
-
[LlmCapabilities.analyze]: "claude-sonnet-4-6",
|
|
15478
|
-
[LlmCapabilities.classify]: "claude-haiku-4-5"
|
|
15479
|
-
},
|
|
15480
|
-
[AgentProviderIds.openai]: {
|
|
15481
|
-
[LlmCapabilities.agent]: "gpt-5.1",
|
|
15482
|
-
[LlmCapabilities.analyze]: "gpt-5-mini",
|
|
15483
|
-
[LlmCapabilities.classify]: "gpt-5-nano"
|
|
15484
|
-
},
|
|
15485
|
-
[AgentProviderIds.gemini]: {
|
|
15486
|
-
// Gemini's Flash is already cheap + capable; Flash-Lite is the
|
|
15487
|
-
// dedicated micro tier for classify. Analyze stays on flash because
|
|
15488
|
-
// flash-lite drops too much quality for structured synthesis.
|
|
15489
|
-
// Exact IDs, never Google's `-latest` aliases: pi-ai derives request
|
|
15490
|
-
// options (thinking level) from the catalog entry for the ID it is given,
|
|
15491
|
-
// and an alias entry can lag the model it serves. `gemini-flash-latest`
|
|
15492
|
-
// allows MINIMAL thinking while the 3.8 Flash it resolves to rejects it,
|
|
15493
|
-
// so every Aero turn failed. Sweeps can use the alias; Aero cannot.
|
|
15494
|
-
[LlmCapabilities.agent]: "gemini-3.8-flash",
|
|
15495
|
-
[LlmCapabilities.analyze]: "gemini-3.8-flash",
|
|
15496
|
-
[LlmCapabilities.classify]: "gemini-3.5-flash-lite"
|
|
15497
|
-
},
|
|
15498
|
-
[AgentProviderIds.zai]: {
|
|
15499
|
-
// GLM lineage: 5.2 replaced 5.1, which pi-ai 0.87 dropped from its
|
|
15500
|
-
// catalog; 5-turbo is the cheaper tier good for structured tasks and
|
|
15501
|
-
// classification.
|
|
15502
|
-
[LlmCapabilities.agent]: "glm-5.2",
|
|
15503
|
-
[LlmCapabilities.analyze]: "glm-5-turbo",
|
|
15504
|
-
[LlmCapabilities.classify]: "glm-5-turbo"
|
|
15505
|
-
}
|
|
15506
|
-
};
|
|
15507
|
-
var AGENT_PROVIDERS = {
|
|
15508
|
-
[AgentProviderIds.claude]: {
|
|
15509
|
-
piAiProvider: "anthropic",
|
|
15510
|
-
label: "Anthropic (Claude)",
|
|
15511
|
-
defaultModel: PROVIDER_MODELS[AgentProviderIds.claude][LlmCapabilities.agent],
|
|
15512
|
-
autoDetectPriority: 0
|
|
15513
|
-
},
|
|
15514
|
-
[AgentProviderIds.openai]: {
|
|
15515
|
-
piAiProvider: "openai",
|
|
15516
|
-
label: "OpenAI",
|
|
15517
|
-
defaultModel: PROVIDER_MODELS[AgentProviderIds.openai][LlmCapabilities.agent],
|
|
15518
|
-
autoDetectPriority: 1
|
|
15519
|
-
},
|
|
15520
|
-
[AgentProviderIds.gemini]: {
|
|
15521
|
-
piAiProvider: "google",
|
|
15522
|
-
label: "Google (Gemini)",
|
|
15523
|
-
defaultModel: PROVIDER_MODELS[AgentProviderIds.gemini][LlmCapabilities.agent],
|
|
15524
|
-
autoDetectPriority: 2
|
|
15525
|
-
},
|
|
15526
|
-
[AgentProviderIds.zai]: {
|
|
15527
|
-
piAiProvider: "zai",
|
|
15528
|
-
label: "Z.ai (GLM)",
|
|
15529
|
-
defaultModel: PROVIDER_MODELS[AgentProviderIds.zai][LlmCapabilities.agent],
|
|
15530
|
-
autoDetectPriority: 3
|
|
15531
|
-
}
|
|
15532
|
-
};
|
|
15533
|
-
function agentProvidersByPriority() {
|
|
15534
|
-
return Object.keys(AGENT_PROVIDERS).slice().sort((a, b) => AGENT_PROVIDERS[a].autoDetectPriority - AGENT_PROVIDERS[b].autoDetectPriority);
|
|
15535
|
-
}
|
|
15536
|
-
function listAgentProviders() {
|
|
15537
|
-
return AGENT_PROVIDER_IDS;
|
|
15538
|
-
}
|
|
15539
|
-
function getAgentProvider(name) {
|
|
15540
|
-
return AGENT_PROVIDERS[name];
|
|
15541
|
-
}
|
|
15542
|
-
function coerceAgentProvider(value) {
|
|
15543
|
-
if (!value) return void 0;
|
|
15544
|
-
return isAgentProviderId(value) ? value : void 0;
|
|
15545
|
-
}
|
|
15546
|
-
function resolveModelForProvider(provider, modelId) {
|
|
15547
|
-
return resolveModelForCapability(provider, LlmCapabilities.agent, modelId);
|
|
15548
|
-
}
|
|
15549
|
-
function resolveModelForCapability(provider, capability, modelIdOverride) {
|
|
15550
|
-
const entry = AGENT_PROVIDERS[provider];
|
|
15551
|
-
const id = modelIdOverride ?? PROVIDER_MODELS[provider][capability];
|
|
15552
|
-
const model = aeroModels.getModel(entry.piAiProvider, id);
|
|
15553
|
-
if (!model) {
|
|
15554
|
-
throw new Error(
|
|
15555
|
-
`Model '${id}' not found for pi-ai provider '${entry.piAiProvider}'. Verify PROVIDER_MODELS[${provider}][${capability}] against the installed @earendil-works/pi-ai catalog.`
|
|
15556
|
-
);
|
|
15557
|
-
}
|
|
15558
|
-
if (provider === AgentProviderIds.gemini && process.env.GEMINI_BASE_URL) {
|
|
15559
|
-
const base = process.env.GEMINI_BASE_URL.replace(/\/+$/, "");
|
|
15560
|
-
const baseUrl = base.endsWith("/v1beta") ? base : `${base}/v1beta`;
|
|
15561
|
-
return { ...model, baseUrl };
|
|
15562
|
-
}
|
|
15563
|
-
if (provider === AgentProviderIds.zai && process.env.ZAI_BASE_URL) {
|
|
15564
|
-
const baseUrl = process.env.ZAI_BASE_URL.replace(/\/+$/, "");
|
|
15565
|
-
return { ...model, baseUrl };
|
|
15566
|
-
}
|
|
15567
|
-
return model;
|
|
15568
|
-
}
|
|
15569
|
-
function isAgentModelAvailable(provider, id) {
|
|
15570
|
-
return !!aeroModels.getModel(AGENT_PROVIDERS[provider].piAiProvider, id);
|
|
15571
|
-
}
|
|
15572
|
-
function validateAgentProviderRegistry() {
|
|
15573
|
-
for (const provider of listAgentProviders()) {
|
|
15574
|
-
for (const capability of LLM_CAPABILITIES) {
|
|
15575
|
-
resolveModelForCapability(provider, capability);
|
|
15576
|
-
}
|
|
15577
|
-
const entry = AGENT_PROVIDERS[provider];
|
|
15578
|
-
const agentModel = PROVIDER_MODELS[provider][LlmCapabilities.agent];
|
|
15579
|
-
if (entry.defaultModel !== agentModel) {
|
|
15580
|
-
throw new Error(
|
|
15581
|
-
`AGENT_PROVIDERS[${provider}].defaultModel ('${entry.defaultModel}') does not match PROVIDER_MODELS[${provider}].agent ('${agentModel}'). The two must stay in sync \u2014 defaultModel is a backward-compat shortcut to the agent-tier model.`
|
|
15582
|
-
);
|
|
15583
|
-
}
|
|
15584
|
-
}
|
|
15585
|
-
}
|
|
15586
|
-
function resolveApiKeyFor(providerOrPiAi, config) {
|
|
15587
|
-
return resolveApiKeySource(providerOrPiAi, config)?.key;
|
|
15588
|
-
}
|
|
15589
|
-
function resolveApiKeySource(providerOrPiAi, config) {
|
|
15590
|
-
const id = resolveAgentId(providerOrPiAi);
|
|
15591
|
-
if (!id) return void 0;
|
|
15592
|
-
const fromConfig = config.providers?.[id]?.apiKey;
|
|
15593
|
-
if (fromConfig) return { key: fromConfig, source: "config" };
|
|
15594
|
-
const fromEnv = agentProviderApiKeyEnvVars(id).map((name) => process.env[name]).find((value) => !!value);
|
|
15595
|
-
if (fromEnv) return { key: fromEnv, source: "env" };
|
|
15596
|
-
return void 0;
|
|
15597
|
-
}
|
|
15598
|
-
var CATALOG_API_KEY_ENV_VARS = {
|
|
15599
|
-
anthropic: ["ANTHROPIC_OAUTH_TOKEN", "ANTHROPIC_API_KEY"],
|
|
15600
|
-
openai: ["OPENAI_API_KEY"],
|
|
15601
|
-
google: ["GEMINI_API_KEY"],
|
|
15602
|
-
zai: ["ZAI_API_KEY"]
|
|
15603
|
-
};
|
|
15604
|
-
function agentProviderApiKeyEnvVars(id) {
|
|
15605
|
-
const entry = AGENT_PROVIDERS[id];
|
|
15606
|
-
return CATALOG_API_KEY_ENV_VARS[entry.piAiProvider] ?? [`${entry.piAiProvider.toUpperCase()}_API_KEY`];
|
|
15607
|
-
}
|
|
15608
|
-
function agentProviderApiKeyEnvVar(id) {
|
|
15609
|
-
const names = agentProviderApiKeyEnvVars(id);
|
|
15610
|
-
return names[names.length - 1];
|
|
15611
|
-
}
|
|
15612
|
-
function resolveAgentId(providerOrPiAi) {
|
|
15613
|
-
if (isAgentProviderId(providerOrPiAi)) return providerOrPiAi;
|
|
15614
|
-
for (const id of AGENT_PROVIDER_IDS) {
|
|
15615
|
-
if (AGENT_PROVIDERS[id].piAiProvider === providerOrPiAi) return id;
|
|
15616
|
-
}
|
|
15617
|
-
return void 0;
|
|
15618
|
-
}
|
|
15619
|
-
function buildAgentProvidersResponse(config) {
|
|
15620
|
-
const pinned = coerceAgentProvider(config.agent?.provider ?? void 0);
|
|
15621
|
-
const pinnedModel = pinned ? config.agent?.model ?? void 0 : void 0;
|
|
15622
|
-
const providers = listAgentProviders().map((id) => {
|
|
15623
|
-
const entry = AGENT_PROVIDERS[id];
|
|
15624
|
-
const source = resolveApiKeySource(id, config);
|
|
15625
|
-
return {
|
|
15626
|
-
id,
|
|
15627
|
-
label: entry.label,
|
|
15628
|
-
defaultModel: id === pinned && pinnedModel ? pinnedModel : entry.defaultModel,
|
|
15629
|
-
configured: source !== void 0,
|
|
15630
|
-
keySource: source?.source ?? null
|
|
15631
|
-
};
|
|
15632
|
-
});
|
|
15633
|
-
const firstConfigured = agentProvidersByPriority().find((p) => resolveApiKeySource(p, config));
|
|
15634
|
-
return {
|
|
15635
|
-
providers,
|
|
15636
|
-
defaultProvider: pinned ?? firstConfigured ?? null
|
|
15637
|
-
};
|
|
15638
|
-
}
|
|
15639
|
-
|
|
15640
15650
|
// src/agent/session.ts
|
|
15641
15651
|
import fs10 from "fs";
|
|
15642
15652
|
import path9 from "path";
|
|
@@ -17614,6 +17624,7 @@ function createAeroSession(opts) {
|
|
|
17614
17624
|
const provider = opts.provider ?? detectAgentProvider(opts.config);
|
|
17615
17625
|
if (!provider) throw new Error(missingProviderMessage());
|
|
17616
17626
|
const model = resolveAeroModel(provider, opts.modelId);
|
|
17627
|
+
const thinkingLevel = resolveAgentReasoning(process.env, opts.config, provider);
|
|
17617
17628
|
const toolScope = opts.toolScope ?? AeroToolScopes.all;
|
|
17618
17629
|
const toolProfile = opts.toolProfile ?? AeroToolProfiles.default;
|
|
17619
17630
|
const toolCtx = {
|
|
@@ -17633,6 +17644,7 @@ function createAeroSession(opts) {
|
|
|
17633
17644
|
initialState: {
|
|
17634
17645
|
systemPrompt,
|
|
17635
17646
|
model,
|
|
17647
|
+
thinkingLevel,
|
|
17636
17648
|
tools,
|
|
17637
17649
|
...opts.initialMessages ? { messages: opts.initialMessages } : {}
|
|
17638
17650
|
},
|
|
@@ -20966,6 +20978,7 @@ ${lines.join("\n")}
|
|
|
20966
20978
|
const { provider: nextProvider, modelId: nextModelId } = this.resolveTurnModel(preferences, { provider: row.modelProvider, modelId: row.modelId });
|
|
20967
20979
|
if (nextProvider === currentProvider && nextModelId === currentModelId) return;
|
|
20968
20980
|
agent.state.model = resolveAeroModel(nextProvider, nextModelId);
|
|
20981
|
+
agent.state.thinkingLevel = resolveAgentReasoning(process.env, this.opts.config, nextProvider);
|
|
20969
20982
|
this.opts.db.update(agentSessions).set({
|
|
20970
20983
|
modelProvider: nextProvider,
|
|
20971
20984
|
modelId: nextModelId,
|
|
@@ -22917,7 +22930,7 @@ function finalizeResearchRun(db, runId, fatalError) {
|
|
|
22917
22930
|
}
|
|
22918
22931
|
|
|
22919
22932
|
// src/google-marketing-sync.ts
|
|
22920
|
-
import { and as and24, eq as eq30, isNull as isNull4 } from "drizzle-orm";
|
|
22933
|
+
import { and as and24, eq as eq30, isNull as isNull4, sql as sql12 } from "drizzle-orm";
|
|
22921
22934
|
var RUNTIME_FAILURE_REASONS = {
|
|
22922
22935
|
INVALID_INPUT: OutcomeReasonCodes.VALIDATION,
|
|
22923
22936
|
NOT_CONFIGURED: OutcomeReasonCodes.NOT_CONNECTED,
|
|
@@ -23146,10 +23159,12 @@ async function executeGtmMarketingSync(db, runtime, runId, projectId) {
|
|
|
23146
23159
|
throw new Error("Google Marketing runtime returned the wrong GTM snapshot kind.");
|
|
23147
23160
|
}
|
|
23148
23161
|
const graph = snapshot.payload.data;
|
|
23149
|
-
|
|
23162
|
+
const workspaceId = snapshot.metadata.workspaceId;
|
|
23163
|
+
const workspaceReplaced = connection.selectedWorkspaceId !== null && workspaceId !== connection.selectedWorkspaceId && !graph.workspaces.some((workspace) => workspace.id === connection.selectedWorkspaceId) && (workspaceId === null || graph.workspaces.length === 1 && graph.workspaces[0].id === workspaceId);
|
|
23164
|
+
if (snapshot.metadata.accountId !== connection.selectedAccountId || snapshot.metadata.containerId !== connection.selectedContainerId || workspaceId !== connection.selectedWorkspaceId && !workspaceReplaced) {
|
|
23150
23165
|
throw new Error("GTM returned evidence for a different account, container, or workspace.");
|
|
23151
23166
|
}
|
|
23152
|
-
const selectedWorkspace =
|
|
23167
|
+
const selectedWorkspace = workspaceId ? graph.workspaces.find((workspace) => workspace.id === workspaceId) : null;
|
|
23153
23168
|
const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
23154
23169
|
db.transaction((tx) => {
|
|
23155
23170
|
const terminalClaim = tx.update(runs).set({
|
|
@@ -23173,6 +23188,10 @@ async function executeGtmMarketingSync(db, runtime, runId, projectId) {
|
|
|
23173
23188
|
selectedContainerName: graph.container.name,
|
|
23174
23189
|
selectedContainerPublicId: graph.container.publicId,
|
|
23175
23190
|
selectedWorkspaceName: selectedWorkspace?.name ?? null,
|
|
23191
|
+
...workspaceReplaced ? {
|
|
23192
|
+
selectedWorkspaceId: workspaceId,
|
|
23193
|
+
selectionGeneration: sql12`${gtmConnections.selectionGeneration} + 1`
|
|
23194
|
+
} : {},
|
|
23176
23195
|
lastValidatedAt: snapshot.metadata.capturedAt,
|
|
23177
23196
|
lastSnapshotAt: snapshot.metadata.capturedAt,
|
|
23178
23197
|
lastSnapshotId: snapshot.metadata.id,
|
|
@@ -23192,6 +23211,16 @@ async function executeGtmMarketingSync(db, runtime, runId, projectId) {
|
|
|
23192
23211
|
);
|
|
23193
23212
|
}
|
|
23194
23213
|
tx.insert(gtmRawSnapshots).values(gtmSnapshotValues(snapshot)).run();
|
|
23214
|
+
if (workspaceReplaced) {
|
|
23215
|
+
writeAuditLog(tx, {
|
|
23216
|
+
projectId,
|
|
23217
|
+
actor: "system",
|
|
23218
|
+
action: "gtm.workspace-followed",
|
|
23219
|
+
entityType: "gtm-connection",
|
|
23220
|
+
entityId: connection.id,
|
|
23221
|
+
diff: { from: connection.selectedWorkspaceId, to: workspaceId }
|
|
23222
|
+
});
|
|
23223
|
+
}
|
|
23195
23224
|
});
|
|
23196
23225
|
reportOutcome({ status: OutcomeStatuses.succeeded, counts: { items: (graph.live ?? graph.draft)?.graph.tags.length ?? 0 } });
|
|
23197
23226
|
} catch (error) {
|
|
@@ -24826,7 +24855,7 @@ async function createServer(opts) {
|
|
|
24826
24855
|
const recomputeDebts = /* @__PURE__ */ new Map();
|
|
24827
24856
|
let recomputeSequence = 0;
|
|
24828
24857
|
const markAnswerFieldRecompute = (projectId, full) => {
|
|
24829
|
-
opts.db.update(projects).set({ answerFieldsRecompute: full ? "full" :
|
|
24858
|
+
opts.db.update(projects).set({ answerFieldsRecompute: full ? "full" : sql13`CASE WHEN ${projects.answerFieldsRecompute} = 'full' THEN 'full' ELSE 'competitors' END` }).where(eq31(projects.id, projectId)).run();
|
|
24830
24859
|
};
|
|
24831
24860
|
const requestAnswerFieldRecompute = (projectId, projectName, scope, reason) => {
|
|
24832
24861
|
const sequence = ++recomputeSequence;
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
siteCrawlGraphNodes,
|
|
6
6
|
siteCrawlPages,
|
|
7
7
|
siteCrawlSnapshots
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-QNXQHHCP.js";
|
|
9
9
|
import {
|
|
10
10
|
SITE_CRAWL_GRAPH_MAX_EDGES,
|
|
11
11
|
SITE_CRAWL_GRAPH_MAX_NODES,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
factorStatusFromDistribution,
|
|
16
16
|
factorStatusFromScore,
|
|
17
17
|
roundPreservingTotal
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-QS262E4F.js";
|
|
19
19
|
|
|
20
20
|
// src/site-audit-factors.ts
|
|
21
21
|
function recordedSharePct(factor) {
|