@ctcstack/ctcdocs-core 0.19.0 → 0.20.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/dist/index.d.ts +1 -1
- package/dist/site-configuration.d.ts +10 -0
- package/dist/site-configuration.js +30 -5
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/site-configuration.ts +59 -6
package/dist/index.d.ts
CHANGED
|
@@ -11,4 +11,4 @@ export type { AccessClass, AccessModel, ChainReaders, PublishedReaders, Readers,
|
|
|
11
11
|
export { accessFindings } from './access-findings.js';
|
|
12
12
|
export type { AccessFinding } from './access-findings.js';
|
|
13
13
|
export { fetchCharacterLimit, loadSiteConfiguration, MCP_DEFAULTS, parseSiteConfiguration, SiteConfigurationError, } from './site-configuration.js';
|
|
14
|
-
export type { AddressPolicy, BrandConfiguration, DeploymentConfiguration, DeploymentEnvironmentConfiguration, DeploymentEnvironmentConfigurations, DeploymentVisibility, HomeConfiguration, McpConfiguration, McpSearchConfiguration, NavigationConfiguration, SignInConfiguration, SiteConfiguration, SyncConfigurationDefaults, } from './site-configuration.js';
|
|
14
|
+
export type { AddressPolicy, BrandConfiguration, DeploymentConfiguration, DeploymentEnvironmentConfiguration, DeploymentEnvironmentConfigurations, DeploymentVisibility, HomeConfiguration, McpConfiguration, McpRecentConfiguration, McpSearchConfiguration, NavigationConfiguration, SignInConfiguration, SiteConfiguration, SyncConfigurationDefaults, } from './site-configuration.js';
|
|
@@ -185,6 +185,13 @@ export interface McpSearchConfiguration {
|
|
|
185
185
|
/** Characters of passage text one search returns at most, in all. */
|
|
186
186
|
readonly passageCharacters: number;
|
|
187
187
|
}
|
|
188
|
+
/** What `recent` lists (ADR-044). */
|
|
189
|
+
export interface McpRecentConfiguration {
|
|
190
|
+
/** Documents it lists when a call does not ask for a number. */
|
|
191
|
+
readonly defaultResults: number;
|
|
192
|
+
/** Documents a call may ask for at most. */
|
|
193
|
+
readonly results: number;
|
|
194
|
+
}
|
|
188
195
|
/**
|
|
189
196
|
* The MCP server through which AI assistants read the site as the person who
|
|
190
197
|
* connected them (ADR-041). It needs the Worker's sign-in, so it is accepted
|
|
@@ -195,6 +202,9 @@ export interface McpConfiguration {
|
|
|
195
202
|
readonly search: McpSearchConfiguration;
|
|
196
203
|
/** Characters `fetch` returns at most; a longer document is cut there. */
|
|
197
204
|
readonly fetchCharacters: number;
|
|
205
|
+
/** Characters of JSON a `browse` tree takes at most (ADR-044). */
|
|
206
|
+
readonly browseCharacters: number;
|
|
207
|
+
readonly recent: McpRecentConfiguration;
|
|
198
208
|
}
|
|
199
209
|
/** What `mcp` holds when a project sets only `enabled` (ADR-042). */
|
|
200
210
|
export declare const MCP_DEFAULTS: Omit<McpConfiguration, 'enabled'>;
|
|
@@ -27,11 +27,13 @@ export const MCP_DEFAULTS = Object.freeze({
|
|
|
27
27
|
model: '@cf/baai/bge-reranker-base',
|
|
28
28
|
threshold: 0,
|
|
29
29
|
}),
|
|
30
|
-
results:
|
|
30
|
+
results: 15,
|
|
31
31
|
passagesPerResult: 3,
|
|
32
32
|
passageCharacters: 24_000,
|
|
33
33
|
}),
|
|
34
34
|
fetchCharacters: 100_000,
|
|
35
|
+
browseCharacters: 24_000,
|
|
36
|
+
recent: Object.freeze({ defaultResults: 20, results: 50 }),
|
|
35
37
|
});
|
|
36
38
|
/**
|
|
37
39
|
* The characters an assistant reads of a document: the cut `fetch` makes
|
|
@@ -44,8 +46,6 @@ export function fetchCharacterLimit(mcp) {
|
|
|
44
46
|
}
|
|
45
47
|
/** About 10,000 tokens of English: a starting value, not a measured one. */
|
|
46
48
|
const LARGE_DOCUMENT_CHARACTERS = 40_000;
|
|
47
|
-
/** A passage of fewer characters than this says too little to judge by. */
|
|
48
|
-
const SHORTEST_PASSAGE = 100;
|
|
49
49
|
export class SiteConfigurationError extends Error {
|
|
50
50
|
name = 'SiteConfigurationError';
|
|
51
51
|
}
|
|
@@ -246,7 +246,24 @@ function mcpSearch(value) {
|
|
|
246
246
|
reranking,
|
|
247
247
|
results,
|
|
248
248
|
passagesPerResult: optionalNumber(source, 'passagesPerResult', 'mcp.search.passagesPerResult', defaults.passagesPerResult, { min: 1, whole: true }),
|
|
249
|
-
passageCharacters: optionalNumber(source, 'passageCharacters', 'mcp.search.passageCharacters', defaults.passageCharacters,
|
|
249
|
+
passageCharacters: optionalNumber(source, 'passageCharacters', 'mcp.search.passageCharacters', defaults.passageCharacters,
|
|
250
|
+
// Chunks are shown whole, so the budget answers to the chunk size, not
|
|
251
|
+
// to the results: those it cannot hold are listed without text.
|
|
252
|
+
{ min: 1_000, whole: true }),
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
function mcpRecent(value) {
|
|
256
|
+
const defaults = MCP_DEFAULTS.recent;
|
|
257
|
+
if (value === undefined) {
|
|
258
|
+
return defaults;
|
|
259
|
+
}
|
|
260
|
+
const source = record(value, 'mcp.recent');
|
|
261
|
+
knownKeys(source, 'mcp.recent', Object.keys(defaults));
|
|
262
|
+
const results = optionalNumber(source, 'results', 'mcp.recent.results', defaults.results, { min: 1, whole: true });
|
|
263
|
+
// The default, like a set value, is no more than a call may ask for.
|
|
264
|
+
return {
|
|
265
|
+
defaultResults: optionalNumber(source, 'defaultResults', 'mcp.recent.defaultResults', Math.min(defaults.defaultResults, results), { min: 1, max: results, whole: true }),
|
|
266
|
+
results,
|
|
250
267
|
};
|
|
251
268
|
}
|
|
252
269
|
function optionalMegabytes(source, key, path, fallback) {
|
|
@@ -393,7 +410,13 @@ export function parseSiteConfiguration(input) {
|
|
|
393
410
|
let mcp;
|
|
394
411
|
if (root.mcp !== undefined) {
|
|
395
412
|
const source = record(root.mcp, 'mcp');
|
|
396
|
-
knownKeys(source, 'mcp', [
|
|
413
|
+
knownKeys(source, 'mcp', [
|
|
414
|
+
'enabled',
|
|
415
|
+
'search',
|
|
416
|
+
'fetchCharacters',
|
|
417
|
+
'browseCharacters',
|
|
418
|
+
'recent',
|
|
419
|
+
]);
|
|
397
420
|
const enabled = flag(source, 'enabled', 'mcp.enabled');
|
|
398
421
|
if (enabled) {
|
|
399
422
|
if (!signIn) {
|
|
@@ -407,6 +430,8 @@ export function parseSiteConfiguration(input) {
|
|
|
407
430
|
enabled,
|
|
408
431
|
search: mcpSearch(source.search),
|
|
409
432
|
fetchCharacters: optionalNumber(source, 'fetchCharacters', 'mcp.fetchCharacters', MCP_DEFAULTS.fetchCharacters, { min: 1_000, whole: true }),
|
|
433
|
+
browseCharacters: optionalNumber(source, 'browseCharacters', 'mcp.browseCharacters', MCP_DEFAULTS.browseCharacters, { min: 1_000, whole: true }),
|
|
434
|
+
recent: mcpRecent(source.recent),
|
|
410
435
|
};
|
|
411
436
|
}
|
|
412
437
|
const fetchLimit = fetchCharacterLimit(mcp);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ctcstack/ctcdocs-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "Configuration schema, project layout, generated-path allowlist and the published Markdown form shared by the CTCDocs platform packages.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ctcdocs",
|
package/src/index.ts
CHANGED
|
@@ -217,6 +217,14 @@ export interface McpSearchConfiguration {
|
|
|
217
217
|
readonly passageCharacters: number;
|
|
218
218
|
}
|
|
219
219
|
|
|
220
|
+
/** What `recent` lists (ADR-044). */
|
|
221
|
+
export interface McpRecentConfiguration {
|
|
222
|
+
/** Documents it lists when a call does not ask for a number. */
|
|
223
|
+
readonly defaultResults: number;
|
|
224
|
+
/** Documents a call may ask for at most. */
|
|
225
|
+
readonly results: number;
|
|
226
|
+
}
|
|
227
|
+
|
|
220
228
|
/**
|
|
221
229
|
* The MCP server through which AI assistants read the site as the person who
|
|
222
230
|
* connected them (ADR-041). It needs the Worker's sign-in, so it is accepted
|
|
@@ -227,6 +235,9 @@ export interface McpConfiguration {
|
|
|
227
235
|
readonly search: McpSearchConfiguration;
|
|
228
236
|
/** Characters `fetch` returns at most; a longer document is cut there. */
|
|
229
237
|
readonly fetchCharacters: number;
|
|
238
|
+
/** Characters of JSON a `browse` tree takes at most (ADR-044). */
|
|
239
|
+
readonly browseCharacters: number;
|
|
240
|
+
readonly recent: McpRecentConfiguration;
|
|
230
241
|
}
|
|
231
242
|
|
|
232
243
|
/** What `mcp` holds when a project sets only `enabled` (ADR-042). */
|
|
@@ -241,11 +252,13 @@ export const MCP_DEFAULTS: Omit<McpConfiguration, 'enabled'> = Object.freeze({
|
|
|
241
252
|
model: '@cf/baai/bge-reranker-base',
|
|
242
253
|
threshold: 0,
|
|
243
254
|
}),
|
|
244
|
-
results:
|
|
255
|
+
results: 15,
|
|
245
256
|
passagesPerResult: 3,
|
|
246
257
|
passageCharacters: 24_000,
|
|
247
258
|
}),
|
|
248
259
|
fetchCharacters: 100_000,
|
|
260
|
+
browseCharacters: 24_000,
|
|
261
|
+
recent: Object.freeze({ defaultResults: 20, results: 50 }),
|
|
249
262
|
});
|
|
250
263
|
|
|
251
264
|
/**
|
|
@@ -261,9 +274,6 @@ export function fetchCharacterLimit(mcp: McpConfiguration | undefined): number {
|
|
|
261
274
|
/** About 10,000 tokens of English: a starting value, not a measured one. */
|
|
262
275
|
const LARGE_DOCUMENT_CHARACTERS = 40_000;
|
|
263
276
|
|
|
264
|
-
/** A passage of fewer characters than this says too little to judge by. */
|
|
265
|
-
const SHORTEST_PASSAGE = 100;
|
|
266
|
-
|
|
267
277
|
export interface SiteConfiguration {
|
|
268
278
|
/** Required to serve a private environment through the platform's Worker. */
|
|
269
279
|
readonly signIn?: SignInConfiguration;
|
|
@@ -601,11 +611,40 @@ function mcpSearch(value: unknown): McpSearchConfiguration {
|
|
|
601
611
|
'passageCharacters',
|
|
602
612
|
'mcp.search.passageCharacters',
|
|
603
613
|
defaults.passageCharacters,
|
|
604
|
-
|
|
614
|
+
// Chunks are shown whole, so the budget answers to the chunk size, not
|
|
615
|
+
// to the results: those it cannot hold are listed without text.
|
|
616
|
+
{ min: 1_000, whole: true },
|
|
605
617
|
),
|
|
606
618
|
};
|
|
607
619
|
}
|
|
608
620
|
|
|
621
|
+
function mcpRecent(value: unknown): McpRecentConfiguration {
|
|
622
|
+
const defaults = MCP_DEFAULTS.recent;
|
|
623
|
+
if (value === undefined) {
|
|
624
|
+
return defaults;
|
|
625
|
+
}
|
|
626
|
+
const source = record(value, 'mcp.recent');
|
|
627
|
+
knownKeys(source, 'mcp.recent', Object.keys(defaults));
|
|
628
|
+
const results = optionalNumber(
|
|
629
|
+
source,
|
|
630
|
+
'results',
|
|
631
|
+
'mcp.recent.results',
|
|
632
|
+
defaults.results,
|
|
633
|
+
{ min: 1, whole: true },
|
|
634
|
+
);
|
|
635
|
+
// The default, like a set value, is no more than a call may ask for.
|
|
636
|
+
return {
|
|
637
|
+
defaultResults: optionalNumber(
|
|
638
|
+
source,
|
|
639
|
+
'defaultResults',
|
|
640
|
+
'mcp.recent.defaultResults',
|
|
641
|
+
Math.min(defaults.defaultResults, results),
|
|
642
|
+
{ min: 1, max: results, whole: true },
|
|
643
|
+
),
|
|
644
|
+
results,
|
|
645
|
+
};
|
|
646
|
+
}
|
|
647
|
+
|
|
609
648
|
function optionalMegabytes(
|
|
610
649
|
source: Record<string, unknown>,
|
|
611
650
|
key: string,
|
|
@@ -806,7 +845,13 @@ export function parseSiteConfiguration(input: unknown): SiteConfiguration {
|
|
|
806
845
|
let mcp: McpConfiguration | undefined;
|
|
807
846
|
if (root.mcp !== undefined) {
|
|
808
847
|
const source = record(root.mcp, 'mcp');
|
|
809
|
-
knownKeys(source, 'mcp', [
|
|
848
|
+
knownKeys(source, 'mcp', [
|
|
849
|
+
'enabled',
|
|
850
|
+
'search',
|
|
851
|
+
'fetchCharacters',
|
|
852
|
+
'browseCharacters',
|
|
853
|
+
'recent',
|
|
854
|
+
]);
|
|
810
855
|
const enabled = flag(source, 'enabled', 'mcp.enabled');
|
|
811
856
|
if (enabled) {
|
|
812
857
|
if (!signIn) {
|
|
@@ -829,6 +874,14 @@ export function parseSiteConfiguration(input: unknown): SiteConfiguration {
|
|
|
829
874
|
MCP_DEFAULTS.fetchCharacters,
|
|
830
875
|
{ min: 1_000, whole: true },
|
|
831
876
|
),
|
|
877
|
+
browseCharacters: optionalNumber(
|
|
878
|
+
source,
|
|
879
|
+
'browseCharacters',
|
|
880
|
+
'mcp.browseCharacters',
|
|
881
|
+
MCP_DEFAULTS.browseCharacters,
|
|
882
|
+
{ min: 1_000, whole: true },
|
|
883
|
+
),
|
|
884
|
+
recent: mcpRecent(source.recent),
|
|
832
885
|
};
|
|
833
886
|
}
|
|
834
887
|
const fetchLimit = fetchCharacterLimit(mcp);
|