@cyanheads/interpro-mcp-server 0.0.0-stage → 0.1.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/AGENTS.md +375 -0
- package/CLAUDE.md +375 -0
- package/Dockerfile +186 -0
- package/LICENSE +201 -0
- package/README.md +263 -2
- package/changelog/0.1.x/0.1.1.md +20 -0
- package/changelog/template.md +151 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server/tools/definitions/interpro-find-proteins-by-domain.tool.d.ts +177 -0
- package/dist/mcp-server/tools/definitions/interpro-find-proteins-by-domain.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/interpro-find-proteins-by-domain.tool.js +192 -0
- package/dist/mcp-server/tools/definitions/interpro-find-proteins-by-domain.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/interpro-get-clan.tool.d.ts +160 -0
- package/dist/mcp-server/tools/definitions/interpro-get-clan.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/interpro-get-clan.tool.js +259 -0
- package/dist/mcp-server/tools/definitions/interpro-get-clan.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/interpro-get-entry.tool.d.ts +130 -0
- package/dist/mcp-server/tools/definitions/interpro-get-entry.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/interpro-get-entry.tool.js +100 -0
- package/dist/mcp-server/tools/definitions/interpro-get-entry.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/interpro-get-protein-domains.tool.d.ts +172 -0
- package/dist/mcp-server/tools/definitions/interpro-get-protein-domains.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/interpro-get-protein-domains.tool.js +374 -0
- package/dist/mcp-server/tools/definitions/interpro-get-protein-domains.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/interpro-list-reference.tool.d.ts +89 -0
- package/dist/mcp-server/tools/definitions/interpro-list-reference.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/interpro-list-reference.tool.js +99 -0
- package/dist/mcp-server/tools/definitions/interpro-list-reference.tool.js.map +1 -0
- package/dist/mcp-server/tools/definitions/interpro-search-entries.tool.d.ts +184 -0
- package/dist/mcp-server/tools/definitions/interpro-search-entries.tool.d.ts.map +1 -0
- package/dist/mcp-server/tools/definitions/interpro-search-entries.tool.js +155 -0
- package/dist/mcp-server/tools/definitions/interpro-search-entries.tool.js.map +1 -0
- package/dist/services/interpro/budget.d.ts +26 -0
- package/dist/services/interpro/budget.d.ts.map +1 -0
- package/dist/services/interpro/budget.js +41 -0
- package/dist/services/interpro/budget.js.map +1 -0
- package/dist/services/interpro/cursors.d.ts +25 -0
- package/dist/services/interpro/cursors.d.ts.map +1 -0
- package/dist/services/interpro/cursors.js +99 -0
- package/dist/services/interpro/cursors.js.map +1 -0
- package/dist/services/interpro/format.d.ts +17 -0
- package/dist/services/interpro/format.d.ts.map +1 -0
- package/dist/services/interpro/format.js +130 -0
- package/dist/services/interpro/format.js.map +1 -0
- package/dist/services/interpro/http-adapter.d.ts +11 -0
- package/dist/services/interpro/http-adapter.d.ts.map +1 -0
- package/dist/services/interpro/http-adapter.js +134 -0
- package/dist/services/interpro/http-adapter.js.map +1 -0
- package/dist/services/interpro/interpro-service.d.ts +57 -0
- package/dist/services/interpro/interpro-service.d.ts.map +1 -0
- package/dist/services/interpro/interpro-service.js +284 -0
- package/dist/services/interpro/interpro-service.js.map +1 -0
- package/dist/services/interpro/reference.d.ts +31 -0
- package/dist/services/interpro/reference.d.ts.map +1 -0
- package/dist/services/interpro/reference.js +122 -0
- package/dist/services/interpro/reference.js.map +1 -0
- package/dist/services/interpro/relationships.d.ts +38 -0
- package/dist/services/interpro/relationships.d.ts.map +1 -0
- package/dist/services/interpro/relationships.js +70 -0
- package/dist/services/interpro/relationships.js.map +1 -0
- package/dist/services/interpro/routing.d.ts +24 -0
- package/dist/services/interpro/routing.d.ts.map +1 -0
- package/dist/services/interpro/routing.js +106 -0
- package/dist/services/interpro/routing.js.map +1 -0
- package/dist/services/interpro/schemas.d.ts +182 -0
- package/dist/services/interpro/schemas.d.ts.map +1 -0
- package/dist/services/interpro/schemas.js +215 -0
- package/dist/services/interpro/schemas.js.map +1 -0
- package/dist/services/interpro/upstream-errors.d.ts +43 -0
- package/dist/services/interpro/upstream-errors.d.ts.map +1 -0
- package/dist/services/interpro/upstream-errors.js +49 -0
- package/dist/services/interpro/upstream-errors.js.map +1 -0
- package/package.json +103 -4
- package/server.json +85 -0
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview InterPro vocabulary and live release reference tool.
|
|
3
|
+
* @module mcp-server/tools/definitions/interpro-list-reference.tool
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
/** Decode supported vocabulary or retrieve coherent current release counts. */
|
|
8
|
+
export declare const interproListReference: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
9
|
+
topic: z.ZodEnum<{
|
|
10
|
+
accession_patterns: "accession_patterns";
|
|
11
|
+
databases: "databases";
|
|
12
|
+
entry_types: "entry_types";
|
|
13
|
+
release: "release";
|
|
14
|
+
taxa: "taxa";
|
|
15
|
+
}>;
|
|
16
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
17
|
+
topic: z.ZodEnum<{
|
|
18
|
+
accession_patterns: "accession_patterns";
|
|
19
|
+
databases: "databases";
|
|
20
|
+
entry_types: "entry_types";
|
|
21
|
+
release: "release";
|
|
22
|
+
taxa: "taxa";
|
|
23
|
+
}>;
|
|
24
|
+
items: z.ZodArray<z.ZodObject<{
|
|
25
|
+
id: z.ZodString;
|
|
26
|
+
label: z.ZodString;
|
|
27
|
+
description: z.ZodOptional<z.ZodString>;
|
|
28
|
+
sourceDatabase: z.ZodOptional<z.ZodString>;
|
|
29
|
+
accessionPattern: z.ZodOptional<z.ZodString>;
|
|
30
|
+
example: z.ZodOptional<z.ZodString>;
|
|
31
|
+
taxonId: z.ZodOptional<z.ZodString>;
|
|
32
|
+
}, z.core.$strip>>;
|
|
33
|
+
sourceUrls: z.ZodArray<z.ZodString>;
|
|
34
|
+
release: z.ZodOptional<z.ZodObject<{
|
|
35
|
+
version: z.ZodString;
|
|
36
|
+
date: z.ZodString;
|
|
37
|
+
databaseCounts: z.ZodRecord<z.ZodString, z.ZodJSONSchema>;
|
|
38
|
+
}, z.core.$strip>>;
|
|
39
|
+
}, z.core.$strip>, readonly [{
|
|
40
|
+
readonly reason: "upstream_shape_invalid";
|
|
41
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
42
|
+
readonly when: "Upstream JSON or response structure is incompatible.";
|
|
43
|
+
readonly retryable: false;
|
|
44
|
+
readonly recovery: "Retry the same tool later; call interpro_list_reference with topic release to check upstream availability.";
|
|
45
|
+
readonly thrownBy: "service";
|
|
46
|
+
}, {
|
|
47
|
+
readonly reason: "upstream_response_too_large";
|
|
48
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
49
|
+
readonly when: "An upstream response exceeds 4 MiB.";
|
|
50
|
+
readonly retryable: false;
|
|
51
|
+
readonly recovery: "Retry list tools with a smaller limit, or retrieve individual members with interpro_get_entry instead of a large clan.";
|
|
52
|
+
readonly thrownBy: "service";
|
|
53
|
+
}, {
|
|
54
|
+
readonly reason: "release_changed";
|
|
55
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
56
|
+
readonly when: "Release metadata and count responses advertise different versions.";
|
|
57
|
+
readonly retryable: true;
|
|
58
|
+
readonly recovery: "Retry interpro_list_reference with topic release after the upstream release update finishes.";
|
|
59
|
+
readonly thrownBy: "service";
|
|
60
|
+
}, {
|
|
61
|
+
readonly reason: "upstream_rejected";
|
|
62
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
63
|
+
readonly when: "InterPro returns an unhandled redirect or client rejection.";
|
|
64
|
+
readonly retryable: false;
|
|
65
|
+
readonly recovery: "Retry the same tool later; call interpro_list_reference with topic release to check upstream availability.";
|
|
66
|
+
readonly thrownBy: "service";
|
|
67
|
+
}, {
|
|
68
|
+
readonly reason: "upstream_unavailable";
|
|
69
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
70
|
+
readonly when: "InterPro has a network or server failure; HTTP 501 is not retryable.";
|
|
71
|
+
readonly retryable: true;
|
|
72
|
+
readonly recovery: "Retry the same tool later; call interpro_list_reference with topic release to check upstream availability.";
|
|
73
|
+
readonly thrownBy: "service";
|
|
74
|
+
}, {
|
|
75
|
+
readonly reason: "upstream_timeout";
|
|
76
|
+
readonly code: JsonRpcErrorCode.Timeout;
|
|
77
|
+
readonly when: "InterPro returns HTTP 408/504 or an attempt exceeds its deadline.";
|
|
78
|
+
readonly retryable: true;
|
|
79
|
+
readonly recovery: "Retry with a smaller limit where available, then repeat the same tool after waiting.";
|
|
80
|
+
readonly thrownBy: "service";
|
|
81
|
+
}, {
|
|
82
|
+
readonly reason: "upstream_rate_limited";
|
|
83
|
+
readonly code: JsonRpcErrorCode.RateLimited;
|
|
84
|
+
readonly when: "InterPro returns HTTP 429.";
|
|
85
|
+
readonly retryable: true;
|
|
86
|
+
readonly recovery: "Wait for retryAfter when supplied, then repeat the same tool with fewer concurrent calls.";
|
|
87
|
+
readonly thrownBy: "service";
|
|
88
|
+
}], undefined>;
|
|
89
|
+
//# sourceMappingURL=interpro-list-reference.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interpro-list-reference.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/interpro-list-reference.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAUjE,+EAA+E;AAC/E,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cA6FhC,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview InterPro vocabulary and live release reference tool.
|
|
3
|
+
* @module mcp-server/tools/definitions/interpro-list-reference.tool
|
|
4
|
+
*/
|
|
5
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
import { formatInterpro } from '../../../services/interpro/format.js';
|
|
8
|
+
import { getInterproService } from '../../../services/interpro/interpro-service.js';
|
|
9
|
+
import { ReferenceItemSchema, ReferenceTopicSchema, staticReference, } from '../../../services/interpro/reference.js';
|
|
10
|
+
import { JsonObjectSchema } from '../../../services/interpro/schemas.js';
|
|
11
|
+
/** Decode supported vocabulary or retrieve coherent current release counts. */
|
|
12
|
+
export const interproListReference = tool('interpro_list_reference', {
|
|
13
|
+
title: 'InterPro reference vocabulary',
|
|
14
|
+
description: 'List supported InterPro database slugs, entry types, accession routing patterns, common taxon IDs, or current release information.',
|
|
15
|
+
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
|
|
16
|
+
auth: ['tool:interpro_list_reference:read'],
|
|
17
|
+
input: z.object({ topic: ReferenceTopicSchema }),
|
|
18
|
+
output: z.object({
|
|
19
|
+
topic: ReferenceTopicSchema,
|
|
20
|
+
items: z
|
|
21
|
+
.array(ReferenceItemSchema)
|
|
22
|
+
.describe('Applicable reference vocabulary; empty for release.'),
|
|
23
|
+
sourceUrls: z.array(z.string()).describe('Official reference sources.'),
|
|
24
|
+
release: z
|
|
25
|
+
.object({
|
|
26
|
+
version: z.string().describe('Greatest numeric release version.'),
|
|
27
|
+
date: z.string().describe('Release date supplied by InterPro.'),
|
|
28
|
+
databaseCounts: JsonObjectSchema.describe('Complete entry aggregate response.'),
|
|
29
|
+
})
|
|
30
|
+
.optional()
|
|
31
|
+
.describe('Current live release metadata when requested.'),
|
|
32
|
+
}),
|
|
33
|
+
errors: [
|
|
34
|
+
{
|
|
35
|
+
reason: 'upstream_shape_invalid',
|
|
36
|
+
code: JsonRpcErrorCode.ServiceUnavailable,
|
|
37
|
+
when: 'Upstream JSON or response structure is incompatible.',
|
|
38
|
+
retryable: false,
|
|
39
|
+
recovery: 'Retry the same tool later; call interpro_list_reference with topic release to check upstream availability.',
|
|
40
|
+
thrownBy: 'service',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
reason: 'upstream_response_too_large',
|
|
44
|
+
code: JsonRpcErrorCode.ServiceUnavailable,
|
|
45
|
+
when: 'An upstream response exceeds 4 MiB.',
|
|
46
|
+
retryable: false,
|
|
47
|
+
recovery: 'Retry list tools with a smaller limit, or retrieve individual members with interpro_get_entry instead of a large clan.',
|
|
48
|
+
thrownBy: 'service',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
reason: 'release_changed',
|
|
52
|
+
code: JsonRpcErrorCode.ServiceUnavailable,
|
|
53
|
+
when: 'Release metadata and count responses advertise different versions.',
|
|
54
|
+
retryable: true,
|
|
55
|
+
recovery: 'Retry interpro_list_reference with topic release after the upstream release update finishes.',
|
|
56
|
+
thrownBy: 'service',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
reason: 'upstream_rejected',
|
|
60
|
+
code: JsonRpcErrorCode.ServiceUnavailable,
|
|
61
|
+
when: 'InterPro returns an unhandled redirect or client rejection.',
|
|
62
|
+
retryable: false,
|
|
63
|
+
recovery: 'Retry the same tool later; call interpro_list_reference with topic release to check upstream availability.',
|
|
64
|
+
thrownBy: 'service',
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
reason: 'upstream_unavailable',
|
|
68
|
+
code: JsonRpcErrorCode.ServiceUnavailable,
|
|
69
|
+
when: 'InterPro has a network or server failure; HTTP 501 is not retryable.',
|
|
70
|
+
retryable: true,
|
|
71
|
+
recovery: 'Retry the same tool later; call interpro_list_reference with topic release to check upstream availability.',
|
|
72
|
+
thrownBy: 'service',
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
reason: 'upstream_timeout',
|
|
76
|
+
code: JsonRpcErrorCode.Timeout,
|
|
77
|
+
when: 'InterPro returns HTTP 408/504 or an attempt exceeds its deadline.',
|
|
78
|
+
retryable: true,
|
|
79
|
+
recovery: 'Retry with a smaller limit where available, then repeat the same tool after waiting.',
|
|
80
|
+
thrownBy: 'service',
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
reason: 'upstream_rate_limited',
|
|
84
|
+
code: JsonRpcErrorCode.RateLimited,
|
|
85
|
+
when: 'InterPro returns HTTP 429.',
|
|
86
|
+
retryable: true,
|
|
87
|
+
recovery: 'Wait for retryAfter when supplied, then repeat the same tool with fewer concurrent calls.',
|
|
88
|
+
thrownBy: 'service',
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
async handler(input, ctx) {
|
|
92
|
+
if (input.topic !== 'release')
|
|
93
|
+
return { topic: input.topic, ...staticReference(input.topic) };
|
|
94
|
+
const { sourceUrls, ...release } = await getInterproService().release(ctx);
|
|
95
|
+
return { topic: input.topic, items: [], sourceUrls, release };
|
|
96
|
+
},
|
|
97
|
+
format: formatInterpro,
|
|
98
|
+
});
|
|
99
|
+
//# sourceMappingURL=interpro-list-reference.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interpro-list-reference.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/interpro-list-reference.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Cursor-paged entry and signature discovery.
|
|
3
|
+
* @module mcp-server/tools/definitions/interpro-search-entries.tool
|
|
4
|
+
*/
|
|
5
|
+
import { z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
/** Search or browse one database without per-record detail requests. */
|
|
8
|
+
export declare const interproSearchEntries: import("@cyanheads/mcp-ts-core").ToolDefinition<z.ZodObject<{
|
|
9
|
+
sourceDatabase: z.ZodPreprocess<z.ZodDefault<z.ZodEnum<{
|
|
10
|
+
antifam: "antifam";
|
|
11
|
+
cathgene3d: "cathgene3d";
|
|
12
|
+
cdd: "cdd";
|
|
13
|
+
hamap: "hamap";
|
|
14
|
+
interpro: "interpro";
|
|
15
|
+
ncbifam: "ncbifam";
|
|
16
|
+
panther: "panther";
|
|
17
|
+
pfam: "pfam";
|
|
18
|
+
pirsf: "pirsf";
|
|
19
|
+
prints: "prints";
|
|
20
|
+
profile: "profile";
|
|
21
|
+
prosite: "prosite";
|
|
22
|
+
sfld: "sfld";
|
|
23
|
+
smart: "smart";
|
|
24
|
+
ssf: "ssf";
|
|
25
|
+
}>>, unknown>;
|
|
26
|
+
query: z.ZodPreprocess<z.ZodOptional<z.ZodString>, unknown>;
|
|
27
|
+
entryType: z.ZodPreprocess<z.ZodOptional<z.ZodEnum<{
|
|
28
|
+
active_site: "active_site";
|
|
29
|
+
binding_site: "binding_site";
|
|
30
|
+
coiled_coil: "coiled_coil";
|
|
31
|
+
conserved_site: "conserved_site";
|
|
32
|
+
disordered: "disordered";
|
|
33
|
+
domain: "domain";
|
|
34
|
+
family: "family";
|
|
35
|
+
homologous_superfamily: "homologous_superfamily";
|
|
36
|
+
ptm: "ptm";
|
|
37
|
+
region: "region";
|
|
38
|
+
repeat: "repeat";
|
|
39
|
+
}>>, unknown>;
|
|
40
|
+
goTerm: z.ZodPreprocess<z.ZodOptional<z.ZodString>, unknown>;
|
|
41
|
+
goCategory: z.ZodPreprocess<z.ZodOptional<z.ZodEnum<{
|
|
42
|
+
C: "C";
|
|
43
|
+
F: "F";
|
|
44
|
+
P: "P";
|
|
45
|
+
}>>, unknown>;
|
|
46
|
+
integratedInto: z.ZodPreprocess<z.ZodOptional<z.ZodString>, unknown>;
|
|
47
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
48
|
+
cursor: z.ZodPreprocess<z.ZodOptional<z.ZodString>, unknown>;
|
|
49
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
50
|
+
query: z.ZodObject<{
|
|
51
|
+
sourceDatabase: z.ZodEnum<{
|
|
52
|
+
antifam: "antifam";
|
|
53
|
+
cathgene3d: "cathgene3d";
|
|
54
|
+
cdd: "cdd";
|
|
55
|
+
hamap: "hamap";
|
|
56
|
+
interpro: "interpro";
|
|
57
|
+
ncbifam: "ncbifam";
|
|
58
|
+
panther: "panther";
|
|
59
|
+
pfam: "pfam";
|
|
60
|
+
pirsf: "pirsf";
|
|
61
|
+
prints: "prints";
|
|
62
|
+
profile: "profile";
|
|
63
|
+
prosite: "prosite";
|
|
64
|
+
sfld: "sfld";
|
|
65
|
+
smart: "smart";
|
|
66
|
+
ssf: "ssf";
|
|
67
|
+
}>;
|
|
68
|
+
query: z.ZodOptional<z.ZodString>;
|
|
69
|
+
entryType: z.ZodOptional<z.ZodEnum<{
|
|
70
|
+
active_site: "active_site";
|
|
71
|
+
binding_site: "binding_site";
|
|
72
|
+
coiled_coil: "coiled_coil";
|
|
73
|
+
conserved_site: "conserved_site";
|
|
74
|
+
disordered: "disordered";
|
|
75
|
+
domain: "domain";
|
|
76
|
+
family: "family";
|
|
77
|
+
homologous_superfamily: "homologous_superfamily";
|
|
78
|
+
ptm: "ptm";
|
|
79
|
+
region: "region";
|
|
80
|
+
repeat: "repeat";
|
|
81
|
+
}>>;
|
|
82
|
+
goTerm: z.ZodOptional<z.ZodString>;
|
|
83
|
+
goCategory: z.ZodOptional<z.ZodEnum<{
|
|
84
|
+
C: "C";
|
|
85
|
+
F: "F";
|
|
86
|
+
P: "P";
|
|
87
|
+
}>>;
|
|
88
|
+
integratedInto: z.ZodOptional<z.ZodString>;
|
|
89
|
+
}, z.core.$strip>;
|
|
90
|
+
entries: z.ZodArray<z.ZodObject<{
|
|
91
|
+
accession: z.ZodString;
|
|
92
|
+
source_database: z.ZodString;
|
|
93
|
+
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
94
|
+
type: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
95
|
+
integrated: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
96
|
+
member_databases: z.ZodOptional<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>>>>;
|
|
97
|
+
go_terms: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
98
|
+
identifier: z.ZodString;
|
|
99
|
+
name: z.ZodString;
|
|
100
|
+
category: z.ZodObject<{
|
|
101
|
+
code: z.ZodString;
|
|
102
|
+
name: z.ZodString;
|
|
103
|
+
}, z.core.$catchall<z.ZodJSONSchema>>;
|
|
104
|
+
}, z.core.$catchall<z.ZodJSONSchema>>>>>;
|
|
105
|
+
}, z.core.$catchall<z.ZodJSONSchema>>>;
|
|
106
|
+
page: z.ZodObject<{
|
|
107
|
+
total: z.ZodNumber;
|
|
108
|
+
returned: z.ZodNumber;
|
|
109
|
+
limit: z.ZodNumber;
|
|
110
|
+
hasMore: z.ZodBoolean;
|
|
111
|
+
nextCursor: z.ZodOptional<z.ZodString>;
|
|
112
|
+
}, z.core.$strip>;
|
|
113
|
+
sourceUrl: z.ZodString;
|
|
114
|
+
}, z.core.$strip>, readonly [{
|
|
115
|
+
readonly reason: "database_mismatch";
|
|
116
|
+
readonly code: JsonRpcErrorCode.ValidationError;
|
|
117
|
+
readonly when: "Integration filtering is requested on the integrating database.";
|
|
118
|
+
readonly retryable: false;
|
|
119
|
+
readonly recovery: "Call interpro_list_reference with topic accession_patterns, then retry with the matching sourceDatabase.";
|
|
120
|
+
}, {
|
|
121
|
+
readonly reason: "invalid_cursor";
|
|
122
|
+
readonly code: JsonRpcErrorCode.ValidationError;
|
|
123
|
+
readonly when: "Cursor decoding or scope fails, or upstream rejects continuation.";
|
|
124
|
+
readonly retryable: false;
|
|
125
|
+
readonly recovery: "Repeat the same tool without cursor to restart pagination, keeping the intended filters.";
|
|
126
|
+
readonly thrownBy: "service";
|
|
127
|
+
}, {
|
|
128
|
+
readonly reason: "entry_withdrawn";
|
|
129
|
+
readonly code: JsonRpcErrorCode.NotFound;
|
|
130
|
+
readonly when: "InterPro answers the search with HTTP 410, reporting a withdrawn record.";
|
|
131
|
+
readonly retryable: false;
|
|
132
|
+
readonly recovery: "Repeat interpro_search_entries with integratedInto set to a current InterPro accession, or without it; consult interpro_list_reference with topic databases for source names.";
|
|
133
|
+
readonly thrownBy: "service";
|
|
134
|
+
}, {
|
|
135
|
+
readonly reason: "upstream_shape_invalid";
|
|
136
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
137
|
+
readonly when: "Upstream JSON, structure, or continuation is incompatible.";
|
|
138
|
+
readonly retryable: false;
|
|
139
|
+
readonly recovery: "Retry the same tool later; call interpro_list_reference with topic release to check upstream availability.";
|
|
140
|
+
readonly thrownBy: "service";
|
|
141
|
+
}, {
|
|
142
|
+
readonly reason: 'upstream_response_too_large';
|
|
143
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
144
|
+
readonly when: 'An upstream response exceeds 4 MiB.';
|
|
145
|
+
readonly retryable: false;
|
|
146
|
+
readonly recovery: 'Retry list tools with a smaller limit, or retrieve individual members with interpro_get_entry instead of a large clan.';
|
|
147
|
+
readonly thrownBy: 'service';
|
|
148
|
+
}, {
|
|
149
|
+
readonly reason: 'upstream_rejected';
|
|
150
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
151
|
+
readonly when: 'InterPro returns an unhandled redirect or client rejection.';
|
|
152
|
+
readonly retryable: false;
|
|
153
|
+
readonly recovery: 'Retry the same tool later; call interpro_list_reference with topic release to check upstream availability.';
|
|
154
|
+
readonly thrownBy: 'service';
|
|
155
|
+
}, {
|
|
156
|
+
readonly reason: 'upstream_unavailable';
|
|
157
|
+
readonly code: JsonRpcErrorCode.ServiceUnavailable;
|
|
158
|
+
readonly when: 'InterPro has a network or server failure; HTTP 501 is not retryable.';
|
|
159
|
+
readonly retryable: true;
|
|
160
|
+
readonly recovery: 'Retry the same tool later; call interpro_list_reference with topic release to check upstream availability.';
|
|
161
|
+
readonly thrownBy: 'service';
|
|
162
|
+
}, {
|
|
163
|
+
readonly reason: 'upstream_timeout';
|
|
164
|
+
readonly code: JsonRpcErrorCode.Timeout;
|
|
165
|
+
readonly when: 'InterPro returns HTTP 408/504 or an attempt exceeds its deadline.';
|
|
166
|
+
readonly retryable: true;
|
|
167
|
+
readonly recovery: 'Retry with a smaller limit where available, then repeat the same tool after waiting.';
|
|
168
|
+
readonly thrownBy: 'service';
|
|
169
|
+
}, {
|
|
170
|
+
readonly reason: 'upstream_rate_limited';
|
|
171
|
+
readonly code: JsonRpcErrorCode.RateLimited;
|
|
172
|
+
readonly when: 'InterPro returns HTTP 429.';
|
|
173
|
+
readonly retryable: true;
|
|
174
|
+
readonly recovery: 'Wait for retryAfter when supplied, then repeat the same tool with fewer concurrent calls.';
|
|
175
|
+
readonly thrownBy: 'service';
|
|
176
|
+
}], {
|
|
177
|
+
readonly notice: z.ZodOptional<z.ZodString>;
|
|
178
|
+
readonly totalCount: z.ZodOptional<z.ZodNumber>;
|
|
179
|
+
readonly truncated: z.ZodOptional<z.ZodBoolean>;
|
|
180
|
+
readonly shown: z.ZodOptional<z.ZodNumber>;
|
|
181
|
+
readonly cap: z.ZodOptional<z.ZodNumber>;
|
|
182
|
+
readonly effectiveQuery: z.ZodOptional<z.ZodString>;
|
|
183
|
+
}>;
|
|
184
|
+
//# sourceMappingURL=interpro-search-entries.tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interpro-search-entries.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/interpro-search-entries.tool.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAQ,CAAC,EAAE,MAAM,wBAAwB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAmCjE,wEAAwE;AACxE,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4JhC,CAAC"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Cursor-paged entry and signature discovery.
|
|
3
|
+
* @module mcp-server/tools/definitions/interpro-search-entries.tool
|
|
4
|
+
*/
|
|
5
|
+
import { tool, z } from '@cyanheads/mcp-ts-core';
|
|
6
|
+
import { JsonRpcErrorCode } from '@cyanheads/mcp-ts-core/errors';
|
|
7
|
+
import { continuation, decodeCursor, encodeCursor, pageGuidance, } from '../../../services/interpro/cursors.js';
|
|
8
|
+
import { formatInterpro, normalizeImages } from '../../../services/interpro/format.js';
|
|
9
|
+
import { getInterproService } from '../../../services/interpro/interpro-service.js';
|
|
10
|
+
import { ENTRY_ROUTES } from '../../../services/interpro/routing.js';
|
|
11
|
+
import { defaultedString, EntrySummarySchema, EntryTypeSchema, JsonValueSchema, listSchema, optionalString, PageSchema, SourceDatabaseSchema, } from '../../../services/interpro/schemas.js';
|
|
12
|
+
import { UPSTREAM_ERRORS } from '../../../services/interpro/upstream-errors.js';
|
|
13
|
+
const MAX_LIMIT = 100;
|
|
14
|
+
const QuerySchema = z.object({
|
|
15
|
+
sourceDatabase: SourceDatabaseSchema,
|
|
16
|
+
query: z.string().optional().describe('Applied text search.'),
|
|
17
|
+
entryType: EntryTypeSchema.optional().describe('Applied entry type.'),
|
|
18
|
+
goTerm: z.string().optional().describe('Applied GO identifier.'),
|
|
19
|
+
goCategory: z.enum(['P', 'F', 'C']).optional().describe('Applied GO category.'),
|
|
20
|
+
integratedInto: z.string().optional().describe('Applied integrating InterPro accession.'),
|
|
21
|
+
});
|
|
22
|
+
const RowSchema = z
|
|
23
|
+
.object({ metadata: EntrySummarySchema.describe('Entry summary.') })
|
|
24
|
+
.catchall(JsonValueSchema);
|
|
25
|
+
/** Search or browse one database without per-record detail requests. */
|
|
26
|
+
export const interproSearchEntries = tool('interpro_search_entries', {
|
|
27
|
+
title: 'Search InterPro entries',
|
|
28
|
+
description: 'Search InterPro entries or member signatures by text, entry type, GO annotation, or integrated InterPro accession. Results are cursor-paged; use interpro_get_entry for full metadata.',
|
|
29
|
+
annotations: { readOnlyHint: true, idempotentHint: true, openWorldHint: true },
|
|
30
|
+
auth: ['tool:interpro_search_entries:read'],
|
|
31
|
+
input: z.object({
|
|
32
|
+
sourceDatabase: defaultedString(SourceDatabaseSchema.default('interpro')).describe('Database to search; defaults to interpro.'),
|
|
33
|
+
query: optionalString(z.string().trim().min(1).max(300)).describe('Text to search; omit all filters to browse the database.'),
|
|
34
|
+
entryType: optionalString(EntryTypeSchema).describe('Entry annotation type.'),
|
|
35
|
+
goTerm: optionalString(z
|
|
36
|
+
.string()
|
|
37
|
+
.trim()
|
|
38
|
+
.regex(/^GO:\d{7}$/)).describe('GO annotation identifier such as GO:0003677.'),
|
|
39
|
+
goCategory: optionalString(z.enum(['P', 'F', 'C'])).describe('GO category: P biological process, F molecular function, C cellular component.'),
|
|
40
|
+
integratedInto: optionalString(z
|
|
41
|
+
.string()
|
|
42
|
+
.trim()
|
|
43
|
+
.regex(/^IPR\d{6}$/i)).describe('Integrating InterPro accession; requires a member sourceDatabase.'),
|
|
44
|
+
limit: z
|
|
45
|
+
.number()
|
|
46
|
+
.int()
|
|
47
|
+
.min(1)
|
|
48
|
+
.max(MAX_LIMIT)
|
|
49
|
+
.default(20)
|
|
50
|
+
.describe('Page size, from 1 to 100; defaults to 20.'),
|
|
51
|
+
cursor: optionalString(z.string().trim().max(4096)).describe('Opaque nextCursor from this tool with unchanged filters; limit may change.'),
|
|
52
|
+
}),
|
|
53
|
+
output: z.object({
|
|
54
|
+
query: QuerySchema.describe('Applied canonical filters.'),
|
|
55
|
+
entries: z
|
|
56
|
+
.array(EntrySummarySchema.describe('Complete entry summary.'))
|
|
57
|
+
.describe('Complete entry summaries from this page.'),
|
|
58
|
+
page: PageSchema.describe('Continuation and upstream total.'),
|
|
59
|
+
sourceUrl: z.string().describe('Official API source URL.'),
|
|
60
|
+
}),
|
|
61
|
+
enrichment: {
|
|
62
|
+
notice: z.string().optional().describe('Interpretation or recovery guidance.'),
|
|
63
|
+
totalCount: z.number().optional().describe('Upstream total matching records.'),
|
|
64
|
+
truncated: z.boolean().optional().describe('More records remain.'),
|
|
65
|
+
shown: z.number().int().optional().describe('Records returned in this page.'),
|
|
66
|
+
cap: z.number().int().optional().describe('Requested page size.'),
|
|
67
|
+
effectiveQuery: z.string().optional().describe('Applied filters as JSON.'),
|
|
68
|
+
},
|
|
69
|
+
errors: [
|
|
70
|
+
{
|
|
71
|
+
reason: 'database_mismatch',
|
|
72
|
+
code: JsonRpcErrorCode.ValidationError,
|
|
73
|
+
when: 'Integration filtering is requested on the integrating database.',
|
|
74
|
+
retryable: false,
|
|
75
|
+
recovery: 'Call interpro_list_reference with topic accession_patterns, then retry with the matching sourceDatabase.',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
reason: 'invalid_cursor',
|
|
79
|
+
code: JsonRpcErrorCode.ValidationError,
|
|
80
|
+
when: 'Cursor decoding or scope fails, or upstream rejects continuation.',
|
|
81
|
+
retryable: false,
|
|
82
|
+
recovery: 'Repeat the same tool without cursor to restart pagination, keeping the intended filters.',
|
|
83
|
+
thrownBy: 'service',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
reason: 'entry_withdrawn',
|
|
87
|
+
code: JsonRpcErrorCode.NotFound,
|
|
88
|
+
when: 'InterPro answers the search with HTTP 410, reporting a withdrawn record.',
|
|
89
|
+
retryable: false,
|
|
90
|
+
recovery: 'Repeat interpro_search_entries with integratedInto set to a current InterPro accession, or without it; consult interpro_list_reference with topic databases for source names.',
|
|
91
|
+
thrownBy: 'service',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
reason: 'upstream_shape_invalid',
|
|
95
|
+
code: JsonRpcErrorCode.ServiceUnavailable,
|
|
96
|
+
when: 'Upstream JSON, structure, or continuation is incompatible.',
|
|
97
|
+
retryable: false,
|
|
98
|
+
recovery: 'Retry the same tool later; call interpro_list_reference with topic release to check upstream availability.',
|
|
99
|
+
thrownBy: 'service',
|
|
100
|
+
},
|
|
101
|
+
...UPSTREAM_ERRORS,
|
|
102
|
+
],
|
|
103
|
+
async handler(input, ctx) {
|
|
104
|
+
if (input.integratedInto && input.sourceDatabase === 'interpro')
|
|
105
|
+
throw ctx.fail('database_mismatch', 'integratedInto requires a member sourceDatabase.');
|
|
106
|
+
const query = {
|
|
107
|
+
sourceDatabase: input.sourceDatabase,
|
|
108
|
+
...(input.query ? { query: input.query } : {}),
|
|
109
|
+
...(input.entryType ? { entryType: input.entryType } : {}),
|
|
110
|
+
...(input.goTerm ? { goTerm: input.goTerm } : {}),
|
|
111
|
+
...(input.goCategory ? { goCategory: input.goCategory } : {}),
|
|
112
|
+
...(input.integratedInto ? { integratedInto: input.integratedInto.toUpperCase() } : {}),
|
|
113
|
+
};
|
|
114
|
+
const cursor = decodeCursor(input.cursor, 'interpro_search_entries', query);
|
|
115
|
+
const service = getInterproService();
|
|
116
|
+
const response = await service.request(service.begin(ctx), ['entry', query.sourceDatabase], {
|
|
117
|
+
search: query.query,
|
|
118
|
+
type: query.entryType,
|
|
119
|
+
go_term: query.goTerm,
|
|
120
|
+
go_category: query.goCategory,
|
|
121
|
+
integrated: query.integratedInto,
|
|
122
|
+
page_size: input.limit,
|
|
123
|
+
cursor,
|
|
124
|
+
}, listSchema(RowSchema), { continuation: cursor !== undefined });
|
|
125
|
+
const entries = normalizeImages(response.data?.results.map((row) => row.metadata) ?? []);
|
|
126
|
+
const next = continuation(response.data?.next ?? null, new Set(cursor ? [cursor] : []));
|
|
127
|
+
const page = {
|
|
128
|
+
total: response.data?.count ?? 0,
|
|
129
|
+
returned: entries.length,
|
|
130
|
+
limit: input.limit,
|
|
131
|
+
hasMore: next !== undefined,
|
|
132
|
+
...(next ? { nextCursor: encodeCursor('interpro_search_entries', query, next) } : {}),
|
|
133
|
+
};
|
|
134
|
+
ctx.enrich.total(page.total);
|
|
135
|
+
ctx.enrich.echo(JSON.stringify(query));
|
|
136
|
+
if (next)
|
|
137
|
+
ctx.enrich.truncated({
|
|
138
|
+
shown: entries.length,
|
|
139
|
+
cap: input.limit,
|
|
140
|
+
guidance: pageGuidance('interpro_search_entries', 'entries', input.limit, MAX_LIMIT),
|
|
141
|
+
});
|
|
142
|
+
if (!entries.length) {
|
|
143
|
+
const memberText = input.sourceDatabase === 'interpro' &&
|
|
144
|
+
input.query &&
|
|
145
|
+
ENTRY_ROUTES.some((route) => route.source !== 'interpro' && route.pattern.test(input.query ?? ''));
|
|
146
|
+
ctx.enrich.notice('No entries matched the applied filters. Remove query, entryType, goTerm, goCategory, or integratedInto filters that are present; call interpro_list_reference with topic databases to check sourceDatabase.' +
|
|
147
|
+
(memberText
|
|
148
|
+
? ' Use interpro_get_entry with the accession to infer its member database.'
|
|
149
|
+
: ''));
|
|
150
|
+
}
|
|
151
|
+
return { query, entries, page, sourceUrl: response.sourceUrl };
|
|
152
|
+
},
|
|
153
|
+
format: formatInterpro,
|
|
154
|
+
});
|
|
155
|
+
//# sourceMappingURL=interpro-search-entries.tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interpro-search-entries.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/interpro-search-entries.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared byte budget for one tool result's domain output, and whole-item fitting.
|
|
3
|
+
* @module services/interpro/budget
|
|
4
|
+
*/
|
|
5
|
+
/** Most UTF-8 bytes one result's domain output may occupy when serialized as compact JSON. */
|
|
6
|
+
export declare const RESPONSE_BYTE_BUDGET = 100000;
|
|
7
|
+
/** UTF-8 bytes of a value serialized as compact JSON, the form both result surfaces carry. */
|
|
8
|
+
export declare function jsonByteLength(value: unknown): number;
|
|
9
|
+
/**
|
|
10
|
+
* The largest count from 1 to `max` whose `build(count)` fits {@link RESPONSE_BYTE_BUDGET},
|
|
11
|
+
* found by binary search on the assumption that the built size grows with the count. Returns 1
|
|
12
|
+
* when even one item overflows, so a continuation always advances, and 0 when none remain.
|
|
13
|
+
*/
|
|
14
|
+
export declare function largestFittingCount(max: number, build: (count: number) => unknown): number;
|
|
15
|
+
/** The budget as it reads in notices. */
|
|
16
|
+
export declare const BUDGET_LABEL: string;
|
|
17
|
+
/**
|
|
18
|
+
* Builds the largest whole-item output that fits the budget. `oversized` is set when even the
|
|
19
|
+
* smallest non-empty output exceeds it, so the output carries one indivisible item alone.
|
|
20
|
+
*/
|
|
21
|
+
export declare function fitWithinBudget<T>(max: number, build: (count: number) => T): {
|
|
22
|
+
count: number;
|
|
23
|
+
output: T;
|
|
24
|
+
oversized: boolean;
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=budget.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.d.ts","sourceRoot":"","sources":["../../../src/services/interpro/budget.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,8FAA8F;AAC9F,eAAO,MAAM,oBAAoB,SAAU,CAAC;AAE5C,8FAA8F;AAC9F,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAErD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,MAAM,CAU1F;AAED,yCAAyC;AACzC,eAAO,MAAM,YAAY,QAAyE,CAAC;AAEnG;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAC/B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,CAAC,GAC1B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAIlD"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared byte budget for one tool result's domain output, and whole-item fitting.
|
|
3
|
+
* @module services/interpro/budget
|
|
4
|
+
*/
|
|
5
|
+
/** Most UTF-8 bytes one result's domain output may occupy when serialized as compact JSON. */
|
|
6
|
+
export const RESPONSE_BYTE_BUDGET = 100_000;
|
|
7
|
+
/** UTF-8 bytes of a value serialized as compact JSON, the form both result surfaces carry. */
|
|
8
|
+
export function jsonByteLength(value) {
|
|
9
|
+
return Buffer.byteLength(JSON.stringify(value), 'utf8');
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The largest count from 1 to `max` whose `build(count)` fits {@link RESPONSE_BYTE_BUDGET},
|
|
13
|
+
* found by binary search on the assumption that the built size grows with the count. Returns 1
|
|
14
|
+
* when even one item overflows, so a continuation always advances, and 0 when none remain.
|
|
15
|
+
*/
|
|
16
|
+
export function largestFittingCount(max, build) {
|
|
17
|
+
if (max <= 0)
|
|
18
|
+
return 0;
|
|
19
|
+
let fits = 1;
|
|
20
|
+
let overflows = max + 1;
|
|
21
|
+
while (overflows - fits > 1) {
|
|
22
|
+
const middle = Math.floor((fits + overflows) / 2);
|
|
23
|
+
if (jsonByteLength(build(middle)) <= RESPONSE_BYTE_BUDGET)
|
|
24
|
+
fits = middle;
|
|
25
|
+
else
|
|
26
|
+
overflows = middle;
|
|
27
|
+
}
|
|
28
|
+
return fits;
|
|
29
|
+
}
|
|
30
|
+
/** The budget as it reads in notices. */
|
|
31
|
+
export const BUDGET_LABEL = `${RESPONSE_BYTE_BUDGET.toLocaleString('en-US')}-byte response budget`;
|
|
32
|
+
/**
|
|
33
|
+
* Builds the largest whole-item output that fits the budget. `oversized` is set when even the
|
|
34
|
+
* smallest non-empty output exceeds it, so the output carries one indivisible item alone.
|
|
35
|
+
*/
|
|
36
|
+
export function fitWithinBudget(max, build) {
|
|
37
|
+
const count = largestFittingCount(max, build);
|
|
38
|
+
const output = build(count);
|
|
39
|
+
return { count, output, oversized: count > 0 && jsonByteLength(output) > RESPONSE_BYTE_BUDGET };
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=budget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../../../src/services/interpro/budget.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,8FAA8F;AAC9F,MAAM,CAAC,MAAM,oBAAoB,GAAG,OAAO,CAAC;AAE5C,8FAA8F;AAC9F,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;AAC1D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW,EAAE,KAAiC;IAChF,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IACvB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,SAAS,GAAG,GAAG,GAAG,CAAC,CAAC;IACxB,OAAO,SAAS,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QAClD,IAAI,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,oBAAoB;YAAE,IAAI,GAAG,MAAM,CAAC;;YACpE,SAAS,GAAG,MAAM,CAAC;IAC1B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,yCAAyC;AACzC,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,oBAAoB,CAAC,cAAc,CAAC,OAAO,CAAC,uBAAuB,CAAC;AAEnG;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,GAAW,EACX,KAA2B;IAE3B,MAAM,KAAK,GAAG,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,GAAG,CAAC,IAAI,cAAc,CAAC,MAAM,CAAC,GAAG,oBAAoB,EAAE,CAAC;AAClG,CAAC"}
|