@canonry/canonry 5.10.0 → 5.12.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/canonry/references/canonry-cli.md +13 -2
- package/assets/assets/{AuditHistoryPanel-C1mws7FA.js → AuditHistoryPanel-DL_NSpfm.js} +1 -1
- package/assets/assets/{BacklinksPage-DP9BUn0y.js → BacklinksPage-BtcBybtX.js} +1 -1
- package/assets/assets/{HistoryPage-Bmo40fKZ.js → HistoryPage-jXj-qi9c.js} +1 -1
- package/assets/assets/{MeasurementPropertyPage-DyqZVFEx.js → MeasurementPropertyPage-DKw401ok.js} +1 -1
- package/assets/assets/{ProjectPage-DBJvI-H1.js → ProjectPage-og4qfFFD.js} +1 -1
- package/assets/assets/{RunRow-BSZcQ0v6.js → RunRow-nK5iaZe1.js} +1 -1
- package/assets/assets/{RunsPage-CIkLV-XY.js → RunsPage-CMgr3YSF.js} +1 -1
- package/assets/assets/{SettingsPage-TJ6l-L5i.js → SettingsPage-QtElCcew.js} +1 -1
- package/assets/assets/{SiteHealthSection-CKvDNoSp.js → SiteHealthSection-DNdVVl30.js} +3 -3
- package/assets/assets/{TrafficPage-BNaCL4v4.js → TrafficPage-C0WgvfRj.js} +1 -1
- package/assets/assets/{TrafficSourceDetailPage-WQu7Tf56.js → TrafficSourceDetailPage-jOTedQtt.js} +1 -1
- package/assets/assets/{extract-error-message-DMgow2EC.js → extract-error-message-DO_053o0.js} +1 -1
- package/assets/assets/index-CnVwWE3V.js +86 -0
- package/assets/assets/{index-DQw9KQwS.css → index-EJC8PSbh.css} +1 -1
- package/assets/assets/{react-sigma_core.esm.min-YECPUDRj.js → react-sigma_core.esm.min-DJttq2UK.js} +1 -1
- package/assets/assets/{v2-overview-adapter-BFf9y-xb.js → v2-overview-adapter-BC_oa__K.js} +1 -1
- package/assets/assets/{vendor-lucide-2cuPDw3H.js → vendor-lucide-N6vOpZmh.js} +1 -1
- package/assets/index.html +3 -3
- package/dist/{chunk-KBPSOB55.js → chunk-DOC4QQLS.js} +2110 -1871
- package/dist/{chunk-W67ORZUR.js → chunk-KBSAEALE.js} +123 -32
- package/dist/{chunk-S7D23FEE.js → chunk-LWGYRN3T.js} +2 -2
- package/dist/{chunk-KEMMVSAQ.js → chunk-NYRRWWEE.js} +50 -2
- package/dist/{chunk-HF6MAKWE.js → chunk-S4BIBUCK.js} +2 -2
- package/dist/{chunk-GQ37ALYP.js → chunk-WJGUBZSW.js} +209 -52
- package/dist/cli.js +106 -14
- package/dist/{demo-server-DKH73GRD.js → demo-server-OTXS6ZHS.js} +3 -3
- package/dist/index.d.ts +28 -1
- package/dist/index.js +5 -5
- package/dist/{intelligence-service-7PVUFJTX.js → intelligence-service-K4U55A2J.js} +2 -2
- package/dist/mcp.js +3 -3
- package/package.json +13 -13
- package/assets/assets/index-BHIRnvQi.js +0 -86
|
@@ -17,12 +17,12 @@ import {
|
|
|
17
17
|
resolveOperatorApiKeyIds,
|
|
18
18
|
runWithUsageTags,
|
|
19
19
|
saveConfigPatch
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-WJGUBZSW.js";
|
|
21
21
|
import {
|
|
22
22
|
deleteSiteCrawlGraphLayout,
|
|
23
23
|
persistSiteCrawlGraphLayout,
|
|
24
24
|
prepareSiteCrawlGraphLayout
|
|
25
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-LWGYRN3T.js";
|
|
26
26
|
import {
|
|
27
27
|
PACKAGE_VERSION
|
|
28
28
|
} from "./chunk-AOJU5LKX.js";
|
|
@@ -151,6 +151,7 @@ import {
|
|
|
151
151
|
readInstalledVersion,
|
|
152
152
|
redactNotificationUrl,
|
|
153
153
|
refreshAccessToken,
|
|
154
|
+
registerAgentConversationRoutes,
|
|
154
155
|
registerOAuthAdminRoutes,
|
|
155
156
|
registerOAuthRoutes,
|
|
156
157
|
requireInstanceAdministrator,
|
|
@@ -178,7 +179,7 @@ import {
|
|
|
178
179
|
siteLivenessState,
|
|
179
180
|
toAlertView,
|
|
180
181
|
usageCounters
|
|
181
|
-
} from "./chunk-
|
|
182
|
+
} from "./chunk-DOC4QQLS.js";
|
|
182
183
|
import {
|
|
183
184
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
184
185
|
AGENT_NONE,
|
|
@@ -299,6 +300,7 @@ import {
|
|
|
299
300
|
isVertexGroundingRedirect,
|
|
300
301
|
mapWithConcurrency,
|
|
301
302
|
maskTelemetryAnonymousId,
|
|
303
|
+
missingDependency,
|
|
302
304
|
nextScheduleUpdatedAt,
|
|
303
305
|
normalizeAgentSlug,
|
|
304
306
|
normalizeIdTokens,
|
|
@@ -335,7 +337,7 @@ import {
|
|
|
335
337
|
visibilityReportRequestSchema,
|
|
336
338
|
winnabilityClassLabel,
|
|
337
339
|
withRetry
|
|
338
|
-
} from "./chunk-
|
|
340
|
+
} from "./chunk-NYRRWWEE.js";
|
|
339
341
|
|
|
340
342
|
// src/runtime-context.ts
|
|
341
343
|
function cliRuntimeContext(env = process.env, stdio = process) {
|
|
@@ -6481,7 +6483,7 @@ function nonBlank(value) {
|
|
|
6481
6483
|
return trimmed ? trimmed : void 0;
|
|
6482
6484
|
}
|
|
6483
6485
|
function resolveBuildCommit(env = process.env) {
|
|
6484
|
-
const embedded = true ? "
|
|
6486
|
+
const embedded = true ? "3cbbec137ff9c498f0b59f30a5e2b84c99af6f40" : void 0;
|
|
6485
6487
|
return nonBlank(embedded) ?? nonBlank(env.CANONRY_COMMIT);
|
|
6486
6488
|
}
|
|
6487
6489
|
function resolveInstanceIdentity(env = process.env) {
|
|
@@ -11775,7 +11777,7 @@ function readStoredGroundingSources(rawResponse) {
|
|
|
11775
11777
|
return result2;
|
|
11776
11778
|
}
|
|
11777
11779
|
async function backfillInsightsCommand(project, opts) {
|
|
11778
|
-
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-
|
|
11780
|
+
const { IntelligenceService: IntelligenceService2 } = await import("./intelligence-service-K4U55A2J.js");
|
|
11779
11781
|
const config = loadConfig();
|
|
11780
11782
|
const db = createClient(config.database);
|
|
11781
11783
|
migrate(db);
|
|
@@ -13864,13 +13866,15 @@ function resolveAgentId(providerOrPiAi) {
|
|
|
13864
13866
|
return void 0;
|
|
13865
13867
|
}
|
|
13866
13868
|
function buildAgentProvidersResponse(config) {
|
|
13869
|
+
const pinned = coerceAgentProvider(config.agent?.provider ?? void 0);
|
|
13870
|
+
const pinnedModel = pinned ? config.agent?.model ?? void 0 : void 0;
|
|
13867
13871
|
const providers = listAgentProviders().map((id) => {
|
|
13868
13872
|
const entry = AGENT_PROVIDERS[id];
|
|
13869
13873
|
const source = resolveApiKeySource(id, config);
|
|
13870
13874
|
return {
|
|
13871
13875
|
id,
|
|
13872
13876
|
label: entry.label,
|
|
13873
|
-
defaultModel: entry.defaultModel,
|
|
13877
|
+
defaultModel: id === pinned && pinnedModel ? pinnedModel : entry.defaultModel,
|
|
13874
13878
|
configured: source !== void 0,
|
|
13875
13879
|
keySource: source?.source ?? null
|
|
13876
13880
|
};
|
|
@@ -13878,7 +13882,7 @@ function buildAgentProvidersResponse(config) {
|
|
|
13878
13882
|
const firstConfigured = agentProvidersByPriority().find((p) => resolveApiKeySource(p, config));
|
|
13879
13883
|
return {
|
|
13880
13884
|
providers,
|
|
13881
|
-
defaultProvider: firstConfigured ?? null
|
|
13885
|
+
defaultProvider: pinned ?? firstConfigured ?? null
|
|
13882
13886
|
};
|
|
13883
13887
|
}
|
|
13884
13888
|
|
|
@@ -14174,6 +14178,9 @@ function mcpToAgentTool(tool, ctx) {
|
|
|
14174
14178
|
}
|
|
14175
14179
|
var AERO_EXCLUDED_MCP_TOOLS = /* @__PURE__ */ new Set([
|
|
14176
14180
|
CanonryMcpToolNames.canonry_agent_clear,
|
|
14181
|
+
CanonryMcpToolNames.canonry_agent_conversations_new,
|
|
14182
|
+
CanonryMcpToolNames.canonry_agent_conversations_resume,
|
|
14183
|
+
CanonryMcpToolNames.canonry_agent_conversations_delete,
|
|
14177
14184
|
CanonryMcpToolNames.canonry_results_clear
|
|
14178
14185
|
]);
|
|
14179
14186
|
function buildMcpAgentTools(registry, ctx, opts = {}) {
|
|
@@ -14841,6 +14848,27 @@ function missingProviderMessage() {
|
|
|
14841
14848
|
const envHints = agentProvidersByPriority().map(agentProviderApiKeyEnvVar).join(" / ");
|
|
14842
14849
|
return `No agent LLM provider configured. Add an API key for one of: ${configHints} in ~/.canonry/config.yaml, or export ${envHints}.`;
|
|
14843
14850
|
}
|
|
14851
|
+
function resolveConfiguredAgentProvider(config) {
|
|
14852
|
+
return coerceAgentProvider(config.agent?.provider);
|
|
14853
|
+
}
|
|
14854
|
+
function describeAgentPin(config) {
|
|
14855
|
+
const provider = resolveConfiguredAgentProvider(config);
|
|
14856
|
+
if (!provider) return null;
|
|
14857
|
+
const model = config.agent?.model ?? getAgentProvider(provider).defaultModel;
|
|
14858
|
+
let modelError = null;
|
|
14859
|
+
try {
|
|
14860
|
+
resolveAeroModel(provider, model);
|
|
14861
|
+
} catch (err) {
|
|
14862
|
+
modelError = err instanceof Error ? err.message : String(err);
|
|
14863
|
+
}
|
|
14864
|
+
return {
|
|
14865
|
+
provider,
|
|
14866
|
+
model,
|
|
14867
|
+
configured: Boolean(resolveApiKeyFor(provider, config)),
|
|
14868
|
+
envVar: agentProviderApiKeyEnvVar(provider),
|
|
14869
|
+
modelError
|
|
14870
|
+
};
|
|
14871
|
+
}
|
|
14844
14872
|
function detectAgentProvider(config) {
|
|
14845
14873
|
for (const provider of agentProvidersByPriority()) {
|
|
14846
14874
|
if (resolveApiKeyFor(provider, config)) return provider;
|
|
@@ -14911,9 +14939,11 @@ function createAeroSession(opts) {
|
|
|
14911
14939
|
return agent;
|
|
14912
14940
|
}
|
|
14913
14941
|
function resolveSessionProviderAndModel(config, opts) {
|
|
14914
|
-
const
|
|
14942
|
+
const pinned = resolveConfiguredAgentProvider(config);
|
|
14943
|
+
const provider = opts?.provider ?? pinned ?? detectAgentProvider(config);
|
|
14915
14944
|
if (!provider) throw new Error(missingProviderMessage());
|
|
14916
|
-
const
|
|
14945
|
+
const pinnedModelId = provider === pinned ? config.agent?.model : void 0;
|
|
14946
|
+
const modelId = opts?.modelId ?? pinnedModelId ?? getAgentProvider(provider).defaultModel;
|
|
14917
14947
|
return { provider, modelId };
|
|
14918
14948
|
}
|
|
14919
14949
|
|
|
@@ -15006,7 +15036,7 @@ async function loadExternalMcpTools(servers, opts = {}) {
|
|
|
15006
15036
|
|
|
15007
15037
|
// src/agent/memory-store.ts
|
|
15008
15038
|
import crypto23 from "crypto";
|
|
15009
|
-
import { and as and16, desc as desc7, eq as eq19, like, sql as sql8 } from "drizzle-orm";
|
|
15039
|
+
import { and as and16, desc as desc7, eq as eq19, like, sql as sql8, or as or2 } from "drizzle-orm";
|
|
15010
15040
|
var COMPACTION_KEY_PREFIX = "compaction:";
|
|
15011
15041
|
var COMPACTION_NOTES_PER_SESSION = 3;
|
|
15012
15042
|
function rowToDto(row) {
|
|
@@ -15060,8 +15090,13 @@ function deleteMemoryEntry(db, projectId, key) {
|
|
|
15060
15090
|
const changes = result2.changes ?? 0;
|
|
15061
15091
|
return changes > 0;
|
|
15062
15092
|
}
|
|
15063
|
-
function loadRecentForHydrate(db, projectId, limit) {
|
|
15064
|
-
return listMemoryEntries(db, projectId, { limit });
|
|
15093
|
+
function loadRecentForHydrate(db, projectId, limit, sessionId) {
|
|
15094
|
+
if (sessionId === void 0) return listMemoryEntries(db, projectId, { limit });
|
|
15095
|
+
const sessionPrefix = `compaction:${sessionId ?? ""}:`;
|
|
15096
|
+
return db.select().from(agentMemory).where(and16(
|
|
15097
|
+
eq19(agentMemory.projectId, projectId),
|
|
15098
|
+
or2(sql8`substr(${agentMemory.key}, 1, ${COMPACTION_KEY_PREFIX.length}) <> ${COMPACTION_KEY_PREFIX}`, sessionId ? sql8`substr(${agentMemory.key}, 1, ${sessionPrefix.length}) = ${sessionPrefix}` : void 0)
|
|
15099
|
+
)).orderBy(desc7(agentMemory.updatedAt)).limit(limit).all().map(rowToDto);
|
|
15065
15100
|
}
|
|
15066
15101
|
function writeCompactionNote(db, args) {
|
|
15067
15102
|
if (Buffer.byteLength(args.summary, "utf8") > AGENT_MEMORY_VALUE_MAX_BYTES) {
|
|
@@ -15337,9 +15372,8 @@ var SessionRegistry = class {
|
|
|
15337
15372
|
if (row.systemPrompt !== systemPrompt) {
|
|
15338
15373
|
this.persistPromptSnapshot(projectId, systemPrompt);
|
|
15339
15374
|
}
|
|
15340
|
-
const effectiveProvider = preferences
|
|
15341
|
-
|
|
15342
|
-
if (preferences?.provider || preferences?.modelId) {
|
|
15375
|
+
const { provider: effectiveProvider, modelId: effectiveModelId } = this.resolveTurnModel(preferences, { provider: row.modelProvider, modelId: row.modelId });
|
|
15376
|
+
if (effectiveProvider !== row.modelProvider || effectiveModelId !== row.modelId) {
|
|
15343
15377
|
this.opts.db.update(agentSessions).set({
|
|
15344
15378
|
modelProvider: effectiveProvider,
|
|
15345
15379
|
modelId: effectiveModelId,
|
|
@@ -15418,7 +15452,7 @@ var SessionRegistry = class {
|
|
|
15418
15452
|
* escape the `<memory>` wrapper are neutralized before interpolation.
|
|
15419
15453
|
*/
|
|
15420
15454
|
buildHydratedSystemPrompt(projectId, basePrompt) {
|
|
15421
|
-
const entries = loadRecentForHydrate(this.opts.db, projectId, MAX_HYDRATE_NOTES);
|
|
15455
|
+
const entries = loadRecentForHydrate(this.opts.db, projectId, MAX_HYDRATE_NOTES, this.loadRow(projectId)?.id ?? null);
|
|
15422
15456
|
if (entries.length === 0) return basePrompt;
|
|
15423
15457
|
let totalBytes = 0;
|
|
15424
15458
|
const kept = [];
|
|
@@ -15472,17 +15506,19 @@ ${lines.join("\n")}
|
|
|
15472
15506
|
* - align `state.tools` to the requested scope/profile (CLI full vs
|
|
15473
15507
|
* dashboard read-only share the same cached Agent; each request
|
|
15474
15508
|
* re-scopes it).
|
|
15475
|
-
* - align `state.model`
|
|
15476
|
-
*
|
|
15477
|
-
*
|
|
15509
|
+
* - align `state.model` on every turn (see `resolveTurnModel`): an
|
|
15510
|
+
* explicit `provider` / `modelId` wins for this turn, then the
|
|
15511
|
+
* `agent.provider` pin, then the session's stored model.
|
|
15512
|
+
* - refuse, naming `agent.provider`, a pinned provider that has no key.
|
|
15478
15513
|
*
|
|
15479
|
-
* Persists the
|
|
15480
|
-
*
|
|
15514
|
+
* Persists the resolved model to the DB row as provenance. Without a pin an
|
|
15515
|
+
* override therefore sticks, as it always has; with a pin, the next turn
|
|
15516
|
+
* that names no provider returns to it.
|
|
15481
15517
|
*/
|
|
15482
15518
|
async acquireForTurn(projectName, preferences) {
|
|
15483
15519
|
preferences?.signal?.throwIfAborted();
|
|
15484
15520
|
if (this.acquisitions.has(projectName)) throw agentBusy(projectName);
|
|
15485
|
-
const agent = this.getOrCreate(projectName);
|
|
15521
|
+
const agent = this.getOrCreate(projectName, preferences);
|
|
15486
15522
|
if (agent.state.isStreaming) {
|
|
15487
15523
|
throw agentBusy(projectName);
|
|
15488
15524
|
}
|
|
@@ -15499,9 +15535,8 @@ ${lines.join("\n")}
|
|
|
15499
15535
|
scope: preferences?.toolScope ?? AeroToolScopes.all,
|
|
15500
15536
|
profile: preferences?.toolProfile ?? AeroToolProfiles.default
|
|
15501
15537
|
});
|
|
15502
|
-
|
|
15503
|
-
|
|
15504
|
-
}
|
|
15538
|
+
this.alignModel(projectName, agent, preferences ?? {});
|
|
15539
|
+
this.assertTurnProviderUsable(projectId);
|
|
15505
15540
|
await this.mergeExternalTools(agent);
|
|
15506
15541
|
const view = { client: this.opts.client, projectName, basePath: this.opts.config.basePath, context: preferences?.context };
|
|
15507
15542
|
const evidence = preferences?.context ? await readAeroViewEvidence(view) : void 0;
|
|
@@ -15580,15 +15615,56 @@ ${lines.join("\n")}
|
|
|
15580
15615
|
this.scopes.set(projectName, want.scope);
|
|
15581
15616
|
this.profiles.set(projectName, want.profile);
|
|
15582
15617
|
}
|
|
15618
|
+
/**
|
|
15619
|
+
* Throw a named, actionable error when the `agent.provider` pin chose this
|
|
15620
|
+
* turn's provider and that provider has no key. Auto-detection only ever
|
|
15621
|
+
* picks a keyed provider, so the pin is the one path that can land a turn on
|
|
15622
|
+
* a keyless one without anything saying so. An explicitly requested provider
|
|
15623
|
+
* keeps its existing behaviour: the caller named it, and the provider's own
|
|
15624
|
+
* error reports the missing key when the prompt is sent.
|
|
15625
|
+
*/
|
|
15626
|
+
assertTurnProviderUsable(projectId) {
|
|
15627
|
+
const provider = coerceAgentProvider(this.loadRow(projectId)?.modelProvider ?? void 0);
|
|
15628
|
+
if (!provider || provider !== resolveConfiguredAgentProvider(this.opts.config)) return;
|
|
15629
|
+
if (resolveApiKeyFor(provider, this.opts.config)) return;
|
|
15630
|
+
throw missingDependency(
|
|
15631
|
+
`Aero is pinned to ${provider} by agent.provider, but no key is configured for it. Set providers.${provider}.apiKey in config.yaml or export ${agentProviderApiKeyEnvVar(provider)}, or change agent.provider.`,
|
|
15632
|
+
{ provider, pinned: true }
|
|
15633
|
+
);
|
|
15634
|
+
}
|
|
15635
|
+
/**
|
|
15636
|
+
* Resolve the provider/model a turn should use: an explicit request outranks
|
|
15637
|
+
* the `agent.provider` pin, which outranks whatever the row last recorded.
|
|
15638
|
+
*
|
|
15639
|
+
* The row is provenance (what answered), not policy (what answers next), so
|
|
15640
|
+
* a configured pin reasserts itself every turn instead of being frozen at
|
|
15641
|
+
* whatever the first session happened to pick -- and survives the
|
|
15642
|
+
* conversation-delete path, which drops the row entirely. With a pin, an
|
|
15643
|
+
* explicit request therefore lasts one turn.
|
|
15644
|
+
*
|
|
15645
|
+
* The model is a function of the request and the config, never of which
|
|
15646
|
+
* provider ran last: naming the pinned provider gets `agent.model` whether or
|
|
15647
|
+
* not the session just came back from another one. The row's model is used
|
|
15648
|
+
* only when nothing is pinned and nothing was requested, which keeps an
|
|
15649
|
+
* unpinned install's override sticky as it always was. A model id is never
|
|
15650
|
+
* forwarded across providers: any other case takes the provider's default.
|
|
15651
|
+
*/
|
|
15652
|
+
resolveTurnModel(preferences, current) {
|
|
15653
|
+
const pinned = resolveConfiguredAgentProvider(this.opts.config);
|
|
15654
|
+
const provider = preferences?.provider ?? pinned ?? current.provider ?? AgentProviderIds.claude;
|
|
15655
|
+
const carried = !preferences?.provider && !pinned && provider === current.provider ? current.modelId ?? void 0 : void 0;
|
|
15656
|
+
const pinnedModelId = provider === pinned ? this.opts.config.agent?.model ?? void 0 : void 0;
|
|
15657
|
+
const modelId = preferences?.modelId ?? pinnedModelId ?? carried ?? getAgentProvider(provider).defaultModel;
|
|
15658
|
+
return { provider, modelId };
|
|
15659
|
+
}
|
|
15583
15660
|
alignModel(projectName, agent, preferences) {
|
|
15584
15661
|
const projectId = this.tryResolveProjectId(projectName);
|
|
15585
15662
|
if (!projectId) return;
|
|
15586
15663
|
const row = this.loadRow(projectId);
|
|
15587
|
-
|
|
15588
|
-
const
|
|
15589
|
-
const
|
|
15590
|
-
const nextModelId = preferences
|
|
15591
|
-
if (!nextModelId) return;
|
|
15664
|
+
if (!row) return;
|
|
15665
|
+
const currentProvider = row.modelProvider;
|
|
15666
|
+
const currentModelId = row.modelId;
|
|
15667
|
+
const { provider: nextProvider, modelId: nextModelId } = this.resolveTurnModel(preferences, { provider: row.modelProvider, modelId: row.modelId });
|
|
15592
15668
|
if (nextProvider === currentProvider && nextModelId === currentModelId) return;
|
|
15593
15669
|
agent.state.model = resolveAeroModel(nextProvider, nextModelId);
|
|
15594
15670
|
this.opts.db.update(agentSessions).set({
|
|
@@ -15597,6 +15673,13 @@ ${lines.join("\n")}
|
|
|
15597
15673
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
15598
15674
|
}).where(eq20(agentSessions.projectId, projectId)).run();
|
|
15599
15675
|
}
|
|
15676
|
+
/** Snapshot pending work without consuming it before an atomic conversation switch. */
|
|
15677
|
+
prepareConversationChange(projectName) {
|
|
15678
|
+
if (this.isBusy(projectName)) throw agentBusy(projectName);
|
|
15679
|
+
this.save(projectName);
|
|
15680
|
+
const pending = this.pending.get(projectName);
|
|
15681
|
+
if (pending?.length) this.updateRow(this.resolveProjectId(projectName), { followUpQueue: JSON.stringify(pending) });
|
|
15682
|
+
}
|
|
15600
15683
|
/** Persist a session's transcript back to the DB. Call after any run settles. */
|
|
15601
15684
|
save(projectName) {
|
|
15602
15685
|
const agent = this.live.get(projectName);
|
|
@@ -16011,6 +16094,7 @@ function resolveProject(db, name) {
|
|
|
16011
16094
|
return row;
|
|
16012
16095
|
}
|
|
16013
16096
|
function registerAgentRoutes(app, opts) {
|
|
16097
|
+
registerAgentConversationRoutes(app, { db: opts.db, runtime: opts.sessionRegistry });
|
|
16014
16098
|
app.get(
|
|
16015
16099
|
"/projects/:name/agent/transcript",
|
|
16016
16100
|
async (request) => {
|
|
@@ -16018,11 +16102,12 @@ function registerAgentRoutes(app, opts) {
|
|
|
16018
16102
|
const project = resolveProject(opts.db, request.params.name);
|
|
16019
16103
|
const row = opts.db.select().from(agentSessions).where(eq22(agentSessions.projectId, project.id)).get();
|
|
16020
16104
|
if (!row) {
|
|
16021
|
-
return { messages: [], modelProvider: null, modelId: null, updatedAt: null };
|
|
16105
|
+
return { conversationId: null, messages: [], modelProvider: null, modelId: null, updatedAt: null };
|
|
16022
16106
|
}
|
|
16023
16107
|
const messages = parseJsonColumn(row.messages, []);
|
|
16024
16108
|
return {
|
|
16025
16109
|
messages,
|
|
16110
|
+
conversationId: row.id,
|
|
16026
16111
|
isStreaming: opts.sessionRegistry.isBusy(project.name),
|
|
16027
16112
|
modelProvider: row.modelProvider,
|
|
16028
16113
|
modelId: row.modelId,
|
|
@@ -16043,6 +16128,7 @@ function registerAgentRoutes(app, opts) {
|
|
|
16043
16128
|
async (request) => {
|
|
16044
16129
|
requireInstanceAdministrator(request);
|
|
16045
16130
|
const project = resolveProject(opts.db, request.params.name);
|
|
16131
|
+
if (opts.sessionRegistry.isBusy(project.name)) throw agentBusy(project.name);
|
|
16046
16132
|
opts.sessionRegistry.reset(project.name);
|
|
16047
16133
|
opts.db.update(agentSessions).set({ messages: "[]", followUpQueue: "[]", updatedAt: (/* @__PURE__ */ new Date()).toISOString() }).where(eq22(agentSessions.projectId, project.id)).run();
|
|
16048
16134
|
return { status: "reset" };
|
|
@@ -16054,6 +16140,10 @@ function registerAgentRoutes(app, opts) {
|
|
|
16054
16140
|
const parsed = agentPromptRequestSchema.safeParse(request.body);
|
|
16055
16141
|
if (!parsed.success) throw validationError(parsed.error.issues.map((issue) => issue.message).join("; "));
|
|
16056
16142
|
const body = parsed.data;
|
|
16143
|
+
if (body.conversationId !== void 0) {
|
|
16144
|
+
const current = opts.db.select({ id: agentSessions.id }).from(agentSessions).where(eq22(agentSessions.projectId, project.id)).get();
|
|
16145
|
+
if ((current?.id ?? null) !== body.conversationId) throw validationError("The active conversation changed. Reload the conversation before sending.");
|
|
16146
|
+
}
|
|
16057
16147
|
const promptText = body.prompt;
|
|
16058
16148
|
const requestedScope = body?.scope === AeroToolScopes.all ? AeroToolScopes.all : AeroToolScopes.readOnly;
|
|
16059
16149
|
const requestedProfile = isAeroToolProfile(body?.profile) ? body.profile : AeroToolProfiles.default;
|
|
@@ -18958,6 +19048,7 @@ async function createServer(opts) {
|
|
|
18958
19048
|
// Resolved fresh each call so a key added at runtime (settings API) shows
|
|
18959
19049
|
// up immediately in the `config.agent-providers` doctor check.
|
|
18960
19050
|
getAgentProviderSummary: () => buildAgentProvidersResponse(opts.config).providers,
|
|
19051
|
+
getAgentPin: () => describeAgentPin(opts.config),
|
|
18961
19052
|
getGoogleMarketingDoctorInput: (ctx) => {
|
|
18962
19053
|
if (!ctx.project) return null;
|
|
18963
19054
|
const googleAds = opts.db.select().from(googleAdsConnections).where(eq25(googleAdsConnections.projectId, ctx.project.id)).get();
|
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
siteCrawlGraphNodes,
|
|
6
6
|
siteCrawlPages,
|
|
7
7
|
siteCrawlSnapshots
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-DOC4QQLS.js";
|
|
9
9
|
import {
|
|
10
10
|
SITE_CRAWL_GRAPH_MAX_EDGES,
|
|
11
11
|
SITE_CRAWL_GRAPH_MAX_NODES,
|
|
12
12
|
TEMPLATE_LINK_RATIO_THRESHOLD
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-NYRRWWEE.js";
|
|
14
14
|
|
|
15
15
|
// src/site-crawl-graph-layout.ts
|
|
16
16
|
import crypto from "crypto";
|
|
@@ -13962,8 +13962,11 @@ var agentProvidersResponseDtoSchema = z45.object({
|
|
|
13962
13962
|
*/
|
|
13963
13963
|
providers: z45.array(agentProviderOptionDtoSchema).default([]),
|
|
13964
13964
|
/**
|
|
13965
|
-
* Provider
|
|
13966
|
-
*
|
|
13965
|
+
* Provider a new session uses when the caller names none: the
|
|
13966
|
+
* `agent.provider` pin when set (reported even without a key, as its
|
|
13967
|
+
* `configured: false` entry), else the first configured provider by
|
|
13968
|
+
* priority. An existing unpinned session keeps its stored provider. Null
|
|
13969
|
+
* when nothing is pinned and nothing is configured.
|
|
13967
13970
|
*/
|
|
13968
13971
|
defaultProvider: agentProviderIdSchema.nullable()
|
|
13969
13972
|
});
|
|
@@ -13980,6 +13983,7 @@ var agentMemoryDeleteRequestSchema = z45.object({
|
|
|
13980
13983
|
});
|
|
13981
13984
|
var agentPromptRequestSchema = z45.object({
|
|
13982
13985
|
prompt: z45.string().trim().min(1),
|
|
13986
|
+
conversationId: z45.string().min(1).nullable().optional(),
|
|
13983
13987
|
provider: agentProviderIdSchema.optional(),
|
|
13984
13988
|
modelId: z45.string().trim().min(1).optional(),
|
|
13985
13989
|
scope: z45.enum(["all", "read-only"]).optional(),
|
|
@@ -13987,6 +13991,43 @@ var agentPromptRequestSchema = z45.object({
|
|
|
13987
13991
|
context: agentViewContextSchema.optional(),
|
|
13988
13992
|
limits: agentTurnLimitsSchema.optional()
|
|
13989
13993
|
});
|
|
13994
|
+
var agentConversationMessageSchema = z45.looseObject({ role: z45.string(), content: z45.unknown().optional() });
|
|
13995
|
+
var agentConversationSummarySchema = z45.object({
|
|
13996
|
+
id: z45.string(),
|
|
13997
|
+
title: z45.string(),
|
|
13998
|
+
active: z45.boolean(),
|
|
13999
|
+
modelProvider: z45.string(),
|
|
14000
|
+
modelId: z45.string(),
|
|
14001
|
+
createdAt: z45.string(),
|
|
14002
|
+
updatedAt: z45.string()
|
|
14003
|
+
});
|
|
14004
|
+
var agentConversationSchema = agentConversationSummarySchema.extend({
|
|
14005
|
+
messages: z45.array(agentConversationMessageSchema),
|
|
14006
|
+
isStreaming: z45.boolean()
|
|
14007
|
+
});
|
|
14008
|
+
var agentConversationListSchema = z45.object({
|
|
14009
|
+
conversations: z45.array(agentConversationSummarySchema),
|
|
14010
|
+
currentConversationId: z45.string().nullable(),
|
|
14011
|
+
nextOffset: z45.number().int().nullable()
|
|
14012
|
+
});
|
|
14013
|
+
var agentConversationCreateSchema = z45.object({
|
|
14014
|
+
id: z45.uuid()
|
|
14015
|
+
}).strict();
|
|
14016
|
+
var agentConversationDeleteSchema = z45.object({ id: z45.string(), status: z45.literal("deleted") });
|
|
14017
|
+
function agentConversationTitle(messages) {
|
|
14018
|
+
for (const message of messages) {
|
|
14019
|
+
if (message.role !== "user") continue;
|
|
14020
|
+
const content = message.content;
|
|
14021
|
+
const text = typeof content === "string" ? content : Array.isArray(content) ? content.flatMap((block) => typeof block === "object" && block !== null && "type" in block && block.type === "text" && "text" in block && typeof block.text === "string" ? [block.text] : []).join(" ") : "";
|
|
14022
|
+
const title = text.replace(/\s+/g, " ").trim();
|
|
14023
|
+
if (title && !title.startsWith("[system]")) return title.length > 80 ? title.slice(0, 79) + "\u2026" : title;
|
|
14024
|
+
}
|
|
14025
|
+
return "New conversation";
|
|
14026
|
+
}
|
|
14027
|
+
var agentConversationListQuerySchema = z45.object({
|
|
14028
|
+
offset: z45.coerce.number().int().min(0).default(0),
|
|
14029
|
+
limit: z45.coerce.number().int().min(1).max(100).default(50)
|
|
14030
|
+
}).strict();
|
|
13990
14031
|
|
|
13991
14032
|
// ../contracts/src/backlinks.ts
|
|
13992
14033
|
import { z as z46 } from "zod";
|
|
@@ -19673,6 +19714,7 @@ export {
|
|
|
19673
19714
|
agentViewContextSchema,
|
|
19674
19715
|
agentTurnLimitsSchema,
|
|
19675
19716
|
agentVisibilityEvidence,
|
|
19717
|
+
agentProviderIdSchema,
|
|
19676
19718
|
agentProvidersResponseDtoSchema,
|
|
19677
19719
|
MemorySources,
|
|
19678
19720
|
AGENT_MEMORY_VALUE_MAX_BYTES,
|
|
@@ -19680,6 +19722,12 @@ export {
|
|
|
19680
19722
|
agentMemoryUpsertRequestSchema,
|
|
19681
19723
|
agentMemoryDeleteRequestSchema,
|
|
19682
19724
|
agentPromptRequestSchema,
|
|
19725
|
+
agentConversationSchema,
|
|
19726
|
+
agentConversationListSchema,
|
|
19727
|
+
agentConversationCreateSchema,
|
|
19728
|
+
agentConversationDeleteSchema,
|
|
19729
|
+
agentConversationTitle,
|
|
19730
|
+
agentConversationListQuerySchema,
|
|
19683
19731
|
backlinkSourceSchema,
|
|
19684
19732
|
BacklinkSources,
|
|
19685
19733
|
computeBacklinkSummaryMetrics,
|
|
@@ -4,14 +4,14 @@ import {
|
|
|
4
4
|
installSkills,
|
|
5
5
|
loadConfigRaw,
|
|
6
6
|
saveConfigPatch
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-WJGUBZSW.js";
|
|
8
8
|
import {
|
|
9
9
|
PACKAGE_VERSION
|
|
10
10
|
} from "./chunk-AOJU5LKX.js";
|
|
11
11
|
import {
|
|
12
12
|
SKILL_MANIFEST_FILENAME,
|
|
13
13
|
SkillsClients
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-NYRRWWEE.js";
|
|
15
15
|
|
|
16
16
|
// src/skills-autosync.ts
|
|
17
17
|
import fs from "fs";
|