@ganju/utils 0.0.14 → 0.0.15

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.
Files changed (70) hide show
  1. package/dist/channelCustomer.d.ts +99 -0
  2. package/dist/channelCustomer.d.ts.map +1 -0
  3. package/dist/channelCustomer.js +533 -0
  4. package/dist/channelDebounce.d.ts +7 -0
  5. package/dist/channelDebounce.d.ts.map +1 -1
  6. package/dist/chunkOverlap.d.ts +2 -0
  7. package/dist/chunkOverlap.d.ts.map +1 -0
  8. package/dist/chunkOverlap.js +9 -0
  9. package/dist/chunking.d.ts.map +1 -1
  10. package/dist/chunking.js +24 -4
  11. package/dist/citations.d.ts +28 -0
  12. package/dist/citations.d.ts.map +1 -0
  13. package/dist/citations.js +111 -0
  14. package/dist/constants.d.ts +26 -0
  15. package/dist/constants.d.ts.map +1 -1
  16. package/dist/constants.js +107 -9
  17. package/dist/index.d.ts +263 -31
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +70 -0
  20. package/dist/jsonSchemaToZodShape.d.ts +5 -1
  21. package/dist/jsonSchemaToZodShape.d.ts.map +1 -1
  22. package/dist/jsonSchemaToZodShape.js +21 -9
  23. package/dist/pagination.d.ts +47 -0
  24. package/dist/pagination.d.ts.map +1 -0
  25. package/dist/pagination.js +160 -0
  26. package/dist/processQueueBatch.d.ts +6 -1
  27. package/dist/processQueueBatch.d.ts.map +1 -1
  28. package/dist/processQueueBatch.js +23 -10
  29. package/dist/queueFailure.d.ts +14 -0
  30. package/dist/queueFailure.d.ts.map +1 -0
  31. package/dist/queueFailure.js +43 -0
  32. package/dist/resourceRerank.d.ts.map +1 -1
  33. package/dist/resourceRerank.js +3 -1
  34. package/dist/schema.d.ts +90 -26
  35. package/dist/schema.d.ts.map +1 -1
  36. package/dist/schema.js +87 -6
  37. package/dist/ssrf.d.ts +1 -0
  38. package/dist/ssrf.d.ts.map +1 -1
  39. package/dist/ssrf.js +48 -12
  40. package/dist/toolConfirmation.d.ts +48 -0
  41. package/dist/toolConfirmation.d.ts.map +1 -1
  42. package/dist/toolConfirmation.js +75 -1
  43. package/dist/toolCount.d.ts +13 -0
  44. package/dist/toolCount.d.ts.map +1 -0
  45. package/dist/toolCount.js +45 -0
  46. package/dist/toolLint.d.ts +1 -1
  47. package/dist/toolLint.d.ts.map +1 -1
  48. package/dist/toolLint.js +20 -0
  49. package/dist/untrustedContent.d.ts +135 -0
  50. package/dist/untrustedContent.d.ts.map +1 -0
  51. package/dist/untrustedContent.js +402 -0
  52. package/package.json +2 -1
  53. package/src/channelCustomer.ts +604 -0
  54. package/src/channelDebounce.ts +17 -0
  55. package/src/chunkOverlap.ts +6 -0
  56. package/src/chunking.ts +25 -4
  57. package/src/citations.ts +127 -0
  58. package/src/constants.ts +111 -9
  59. package/src/index.ts +152 -2
  60. package/src/jsonSchemaToZodShape.ts +31 -13
  61. package/src/pagination.ts +193 -0
  62. package/src/processQueueBatch.ts +42 -12
  63. package/src/queueFailure.ts +63 -0
  64. package/src/resourceRerank.ts +5 -1
  65. package/src/schema.ts +100 -4
  66. package/src/ssrf.ts +40 -11
  67. package/src/toolConfirmation.ts +123 -0
  68. package/src/toolCount.ts +53 -0
  69. package/src/toolLint.ts +27 -0
  70. package/src/untrustedContent.ts +476 -0
@@ -4,7 +4,7 @@
4
4
  // participant's next message is a plain yes. These are the pieces of that rule
5
5
  // that aren't the runner's own bookkeeping.
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.stableJson = exports.isSensitiveTool = exports.formatConfirmationSummary = exports.isConfirmationReply = exports.parseConfirmationButton = exports.confirmationButtonId = exports.confirmationButtonLabels = exports.languageFromPhoneNumber = exports.annotationsForEffect = exports.TOOL_EFFECTS = void 0;
7
+ exports.toolApprovalUrl = exports.toolApprovalStatus = exports.stableJson = exports.isSensitiveProxiedTool = exports.keepProxiedToolMarks = exports.proxiedToolAnnotations = exports.proxiedToolTrust = exports.isSensitiveTool = exports.formatConfirmationSummary = exports.isConfirmationReply = exports.parseConfirmationButton = exports.confirmationButtonId = exports.confirmationButtonLabels = exports.languageFromPhoneNumber = exports.annotationsForEffect = exports.TOOL_EFFECTS = void 0;
8
8
  // What an owner says a tool they wrote does, in the words the dashboard asks
9
9
  // it in, and the MCP annotations each answer stands for: `read` only looks
10
10
  // things up, `write` changes things that can be undone, `sensitive` sends,
@@ -223,6 +223,62 @@ exports.formatConfirmationSummary = formatConfirmationSummary;
223
223
  */
224
224
  const isSensitiveTool = (annotations) => annotations?.readOnlyHint !== true && annotations?.destructiveHint !== false;
225
225
  exports.isSensitiveTool = isSensitiveTool;
226
+ const proxiedToolTrust = (config, remoteToolName) => ({
227
+ trustHints: config?.trustAnnotations === true,
228
+ readOnly: Array.isArray(config?.readOnlyTools) &&
229
+ config.readOnlyTools.includes(remoteToolName)
230
+ });
231
+ exports.proxiedToolTrust = proxiedToolTrust;
232
+ /**
233
+ * The annotations a proxied tool is registered with. A remote server's hints
234
+ * are its own claim about itself, and one that marks a delete read-only would
235
+ * skip every confirmation — so unless the organization chose to trust that
236
+ * server, the read-only and destructive hints are dropped and the tool reads
237
+ * as sensitive by the defaults above. A tool the owner marked as only reading
238
+ * is read-only whatever the remote says, trusted or not. Clients see the
239
+ * same, so they ask about the same tools. The harmless parts (title,
240
+ * openWorldHint, idempotentHint) pass through.
241
+ */
242
+ const proxiedToolAnnotations = (annotations, trust) => {
243
+ const result = { ...annotations };
244
+ if (trust.readOnly) {
245
+ delete result.destructiveHint;
246
+ return { ...result, readOnlyHint: true };
247
+ }
248
+ if (!trust.trustHints) {
249
+ delete result.readOnlyHint;
250
+ delete result.destructiveHint;
251
+ }
252
+ return Object.keys(result).length > 0 ? result : undefined;
253
+ };
254
+ exports.proxiedToolAnnotations = proxiedToolAnnotations;
255
+ // The install-config keys that hold the owner's trust marks above.
256
+ const PROXIED_TOOL_MARK_KEYS = ['trustAnnotations', 'readOnlyTools'];
257
+ /**
258
+ * An install's new config with the owner's trust marks carried over from the
259
+ * stored one wherever the new one doesn't say. A save that only knew about
260
+ * the allow-lists (an older dashboard, a script) must not quietly turn the
261
+ * marks off; one that sends them, even as false or empty, decides.
262
+ */
263
+ const keepProxiedToolMarks = (stored, incoming) => {
264
+ if (!stored ||
265
+ typeof stored !== 'object' ||
266
+ !incoming ||
267
+ typeof incoming !== 'object') {
268
+ return incoming;
269
+ }
270
+ const merged = { ...incoming };
271
+ for (const key of PROXIED_TOOL_MARK_KEYS) {
272
+ if (merged[key] === undefined && key in stored) {
273
+ merged[key] = stored[key];
274
+ }
275
+ }
276
+ return merged;
277
+ };
278
+ exports.keepProxiedToolMarks = keepProxiedToolMarks;
279
+ /** Whether a proxied tool is confirmed, decided as its registration is. */
280
+ const isSensitiveProxiedTool = (annotations, trust) => (0, exports.isSensitiveTool)((0, exports.proxiedToolAnnotations)(annotations, trust));
281
+ exports.isSensitiveProxiedTool = isSensitiveProxiedTool;
226
282
  // JSON with keys sorted at every depth, so two argument objects that say the
227
283
  // same thing serialize the same whatever order the model emitted them in.
228
284
  const stableJson = (value) => {
@@ -237,3 +293,21 @@ const stableJson = (value) => {
237
293
  return JSON.stringify(value) ?? 'null';
238
294
  };
239
295
  exports.stableJson = stableJson;
296
+ /**
297
+ * Where an approval stands. Spent and refused come first, since an answer
298
+ * stays the answer after the window closes; past its time, one never answered
299
+ * or never used can no longer be.
300
+ */
301
+ const toolApprovalStatus = (approval, now = Date.now()) => {
302
+ if (approval.usedAt)
303
+ return 'used';
304
+ if (approval.deniedAt)
305
+ return 'denied';
306
+ if (approval.expiresAt.getTime() <= now)
307
+ return 'expired';
308
+ return approval.approvedAt ? 'approved' : 'pending';
309
+ };
310
+ exports.toolApprovalStatus = toolApprovalStatus;
311
+ /** The dashboard page where the user answers one approval. */
312
+ const toolApprovalUrl = (webUrl, path, approvalId) => `${webUrl.replace(/\/+$/, '')}${path}/${encodeURIComponent(approvalId)}`;
313
+ exports.toolApprovalUrl = toolApprovalUrl;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * An mcp-proxy row exposes each discovered remote tool its allow-list keeps,
3
+ * so a single GitHub install can be dozens of tools. A custom-code row exposes
4
+ * the functions of its published version the allow-list keeps — pass their
5
+ * names as `customCodeFunctions`; without them the row counts as one. Every
6
+ * other row is one tool.
7
+ */
8
+ export declare const countInstallTools: (install: {
9
+ toolKey: string;
10
+ config: unknown;
11
+ metadata: unknown;
12
+ }, customCodeFunctions?: string[]) => number;
13
+ //# sourceMappingURL=toolCount.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolCount.d.ts","sourceRoot":"","sources":["../src/toolCount.ts"],"names":[],"mappings":"AAqBA;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAC5B,SAAS;IACP,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;CACnB,EACD,sBAAsB,MAAM,EAAE,KAC7B,MAiBF,CAAC"}
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ // How many tools an install puts in front of a model, which is what the tool
3
+ // limit counts. Imports nothing, so node --test runs it directly.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.countInstallTools = void 0;
6
+ // The same values as constants.TOOL_DEFINITION_KEY_MCP_PROXY and
7
+ // TOOL_DEFINITION_KEY_CUSTOM_CODE, written out rather than imported, since
8
+ // this file imports nothing.
9
+ const MCP_PROXY_TOOL_KEY = 'mcp-proxy';
10
+ const CUSTOM_CODE_TOOL_KEY = 'custom-code';
11
+ // The tools an allow-list keeps out of `names`. An empty or absent list keeps
12
+ // all of them, as the MCP boot loop reads it.
13
+ const allowedCount = (names, config) => {
14
+ const allowedTools = config
15
+ ?.allowedTools;
16
+ if (!Array.isArray(allowedTools) || allowedTools.length === 0) {
17
+ return names.length;
18
+ }
19
+ const allowed = new Set(allowedTools);
20
+ return names.filter(name => allowed.has(name)).length;
21
+ };
22
+ /**
23
+ * An mcp-proxy row exposes each discovered remote tool its allow-list keeps,
24
+ * so a single GitHub install can be dozens of tools. A custom-code row exposes
25
+ * the functions of its published version the allow-list keeps — pass their
26
+ * names as `customCodeFunctions`; without them the row counts as one. Every
27
+ * other row is one tool.
28
+ */
29
+ const countInstallTools = (install, customCodeFunctions) => {
30
+ if (install.toolKey === CUSTOM_CODE_TOOL_KEY) {
31
+ return customCodeFunctions
32
+ ? allowedCount(customCodeFunctions, install.config)
33
+ : 1;
34
+ }
35
+ if (install.toolKey !== MCP_PROXY_TOOL_KEY)
36
+ return 1;
37
+ const discovered = install.metadata?.discovery?.tools;
38
+ if (!Array.isArray(discovered))
39
+ return 0;
40
+ const names = discovered
41
+ .map(tool => tool?.name)
42
+ .filter((name) => typeof name === 'string');
43
+ return allowedCount(names, install.config);
44
+ };
45
+ exports.countInstallTools = countInstallTools;
@@ -10,7 +10,7 @@ export interface LintableTool {
10
10
  openWorldHint?: boolean;
11
11
  };
12
12
  }
13
- export declare const TOOL_LINT_RULES: readonly ["missing-description", "short-description", "no-usage-guidance", "missing-annotations", "undescribed-input", "overlapping-tools", "too-many-tools"];
13
+ export declare const TOOL_LINT_RULES: readonly ["missing-description", "short-description", "no-usage-guidance", "missing-annotations", "undescribed-input", "reserved-input", "overlapping-tools", "too-many-tools"];
14
14
  export type ToolLintRule = (typeof TOOL_LINT_RULES)[number];
15
15
  export interface ToolLintFinding {
16
16
  rule: ToolLintRule;
@@ -1 +1 @@
1
- {"version":3,"file":"toolLint.d.ts","sourceRoot":"","sources":["../src/toolLint.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE;QACZ,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,aAAa,CAAC,EAAE,OAAO,CAAC;KACzB,CAAC;CACH;AAED,eAAO,MAAM,eAAe,+JAQlB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,YAAY,CAAC;IAGnB,IAAI,CAAC,EAAE,MAAM,CAAC;IAGd,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAEjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAEjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAI9B,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;IAGxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID,eAAO,MAAM,gCAAgC,KAAK,CAAC;AAKnD,eAAO,MAAM,mBAAmB,KAAK,CAAC;AA2JtC;;;GAGG;AACH,eAAO,MAAM,SAAS,GACpB,OAAO,YAAY,EAAE,EACrB,UAAS,eAAoB,KAC5B,eAAe,EA8FjB,CAAC"}
1
+ {"version":3,"file":"toolLint.d.ts","sourceRoot":"","sources":["../src/toolLint.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE;QACZ,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,aAAa,CAAC,EAAE,OAAO,CAAC;KACzB,CAAC;CACH;AAED,eAAO,MAAM,eAAe,iLASlB,CAAC;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5D,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,YAAY,CAAC;IAGnB,IAAI,CAAC,EAAE,MAAM,CAAC;IAGd,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAGjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAEjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IAGf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAI9B,MAAM,CAAC,EAAE,YAAY,EAAE,CAAC;IAGxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID,eAAO,MAAM,gCAAgC,KAAK,CAAC;AAKnD,eAAO,MAAM,mBAAmB,KAAK,CAAC;AA0KtC;;;GAGG;AACH,eAAO,MAAM,SAAS,GACpB,OAAO,YAAY,EAAE,EACrB,UAAS,eAAoB,KAC5B,eAAe,EAwGjB,CAAC"}
package/dist/toolLint.js CHANGED
@@ -19,6 +19,7 @@ exports.TOOL_LINT_RULES = [
19
19
  'no-usage-guidance',
20
20
  'missing-annotations',
21
21
  'undescribed-input',
22
+ 'reserved-input',
22
23
  'overlapping-tools',
23
24
  'too-many-tools'
24
25
  ];
@@ -160,6 +161,16 @@ const undescribedPaths = (schema, prefix = '') => {
160
161
  }
161
162
  return paths;
162
163
  };
164
+ // Top-level input names the server takes for itself. `confirmation` carries
165
+ // the token a sensitive tool's second call brings back: the server replaces a
166
+ // property of that name and strips it before the tool runs, so it never
167
+ // reaches the tool.
168
+ // Kept here rather than imported from constants (MCP_TOOL_CONFIRMATION_ARG),
169
+ // since this file imports nothing.
170
+ const RESERVED_INPUT_NAMES = ['confirmation'];
171
+ const reservedPaths = (schema) => isObject(schema) && isObject(schema.properties)
172
+ ? RESERVED_INPUT_NAMES.filter(name => Object.prototype.hasOwnProperty.call(schema.properties, name))
173
+ : [];
163
174
  const quoted = (name) => `"${name}"`;
164
175
  /**
165
176
  * Check a set of tools for what makes them hard for a model to use. Findings
@@ -225,6 +236,15 @@ const lintTools = (tools, options = {}) => {
225
236
  message: `${quoted(tool.name)} has input properties with no description: ${paths.join(', ')}. A model has to guess what to pass.`
226
237
  });
227
238
  }
239
+ const reserved = reservedPaths(tool.inputSchema);
240
+ if (reserved.length > 0) {
241
+ findings.push({
242
+ rule: 'reserved-input',
243
+ tool: tool.name,
244
+ paths: reserved,
245
+ message: `${quoted(tool.name)} has an input named ${reserved.map(quoted).join(', ')}, which the server keeps for confirming sensitive actions: on a tool it confirms, that property is replaced and its value never reaches the tool. Rename it.`
246
+ });
247
+ }
228
248
  // Each pair once — against the tools after this one, then the rest of the
229
249
  // server — and one finding per tool, so twenty look-alikes are nineteen
230
250
  // lines rather than a hundred and ninety.
@@ -0,0 +1,135 @@
1
+ export declare const UNTRUSTED_CONTENT_TAG = "untrusted_content";
2
+ export declare const UNTRUSTED_CONTENT_META_KEY = "ganju.ai/untrusted";
3
+ export declare const UNTRUSTED_CONTENT_NOTE: string;
4
+ /**
5
+ * Wrap text that came from outside in the marks the model is told about.
6
+ * `source` says where it came from (a tool name, a URI) and is reduced to
7
+ * characters that can't close the attribute.
8
+ */
9
+ export declare const wrapUntrustedContent: (source: string, text: string) => string;
10
+ /**
11
+ * The text inside a wrapped block, for code that reads a tool's result itself
12
+ * (citations parse search results as JSON). Text that isn't one block is
13
+ * returned as it is.
14
+ */
15
+ export declare const unwrapUntrustedContent: (text: string) => string;
16
+ /** Whether a tool result carries the flag set by the server that ran it. */
17
+ export declare const isUntrustedToolResult: (result: unknown) => boolean;
18
+ export declare const INSTRUCTION_WARNING_METADATA_KEY = "instructionWarning";
19
+ export interface InstructionWarning {
20
+ passages: string[];
21
+ checkedAt: string;
22
+ }
23
+ /**
24
+ * The passages of `text` that read like instructions to an AI model, as the
25
+ * document wrote them, at most five and each cut to a readable length. Empty
26
+ * when nothing matched.
27
+ */
28
+ export declare const findInstructionLikeText: (text: string) => string[];
29
+ type ContentBlock = {
30
+ type: string;
31
+ text?: string;
32
+ [key: string]: unknown;
33
+ };
34
+ export interface LabelledToolResult {
35
+ content: ContentBlock[];
36
+ structuredContent?: unknown;
37
+ isError?: boolean;
38
+ _meta?: Record<string, unknown>;
39
+ }
40
+ /**
41
+ * Outside text as a tool result: wrapped, and flagged so that a sensitive call
42
+ * made after it asks first. `flag: false` labels without flagging — for the
43
+ * organization's own knowledge base, where reading a clean document shouldn't
44
+ * make every later action ask.
45
+ */
46
+ export declare const untrustedToolResult: (source: string, text: string, options?: {
47
+ flag?: boolean;
48
+ }) => {
49
+ content: Array<{
50
+ type: "text";
51
+ text: string;
52
+ }>;
53
+ _meta?: Record<string, unknown>;
54
+ };
55
+ /**
56
+ * Mostly the user's own writing, but able to quote someone else's — a draft
57
+ * carrying the email it replies to. Labelled always, flagged only when it
58
+ * reads like instructions, so "show my drafts, then send that one" doesn't
59
+ * ask every time.
60
+ */
61
+ export declare const ownWritingToolResult: (source: string, text: string) => {
62
+ content: Array<{
63
+ type: "text";
64
+ text: string;
65
+ }>;
66
+ _meta?: Record<string, unknown>;
67
+ };
68
+ /**
69
+ * What one of the organization's own integrations (an HTTP endpoint, a custom
70
+ * tool) brought back. The integration is the owner's, but the data may not be
71
+ * — a support ticket, a product review — so its text is wrapped. Flagged only
72
+ * when it reads like instructions: a menu lookup before an order is the
73
+ * ordinary case. A declared output schema makes the structured copy required,
74
+ * so it stays and can't carry the label, but it is read for instructions all
75
+ * the same. Errors pass through as they are: a tool whose error carries
76
+ * outside text labels that part itself (see untrustedErrorResult).
77
+ */
78
+ export declare const labelOwnToolResult: <T extends LabelledToolResult>(result: T, source: string) => T;
79
+ /**
80
+ * A failure whose message carries text from outside — an endpoint's error
81
+ * body, a remote server's or a script's error. `message` is ours and stays
82
+ * first, so the result still reads as an `Error:`; `detail` is wrapped.
83
+ * Flagged always unless `flag: false`, which the organization's own
84
+ * integrations pass with whether the detail reads like instructions.
85
+ */
86
+ export declare const untrustedErrorResult: (message: string, source: string, detail: string, options?: {
87
+ flag?: boolean;
88
+ }) => {
89
+ content: Array<{
90
+ type: "text";
91
+ text: string;
92
+ }>;
93
+ isError: true;
94
+ _meta?: Record<string, unknown>;
95
+ };
96
+ /** Whether text reads like instructions to the model. */
97
+ export declare const readsLikeInstructions: (text: string) => boolean;
98
+ type ResourceContent = {
99
+ uri: string;
100
+ text?: string;
101
+ [key: string]: unknown;
102
+ };
103
+ /**
104
+ * A resource read, as it goes back to the model: each text part wrapped under
105
+ * its own uri, binary parts as they are. `instructionLike` says whether any
106
+ * text part reads like instructions, for the caller deciding whether to flag
107
+ * the session.
108
+ */
109
+ export declare const labelResourceContents: <T extends ResourceContent>(contents: T[]) => {
110
+ contents: T[];
111
+ instructionLike: boolean;
112
+ };
113
+ /**
114
+ * A remote MCP server's tool result, as it goes back through the proxy.
115
+ *
116
+ * Within `maxBytes` the blocks are kept as they are; past it they are
117
+ * flattened to one text block, structured copy included, since the SDK can't
118
+ * return several large blocks in one result. Whatever the remote answers was written by someone
119
+ * else, so every text block is labelled and the result is always flagged.
120
+ * Images and other blocks pass through.
121
+ *
122
+ * A structured copy can't carry the label, and some clients hand the model
123
+ * that copy instead of the text. Proxied tools register no output schema, so
124
+ * the copy is optional: it is folded into the labelled text (as JSON, unless a
125
+ * text block already says exactly that) and dropped. A copy alone counts as
126
+ * content — "(the tool returned no content)" is only for a result that has
127
+ * neither.
128
+ */
129
+ export declare const labelProxiedToolResult: (raw: {
130
+ content?: unknown;
131
+ structuredContent?: unknown;
132
+ isError?: boolean;
133
+ }, source: string, maxBytes: number) => LabelledToolResult;
134
+ export {};
135
+ //# sourceMappingURL=untrustedContent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"untrustedContent.d.ts","sourceRoot":"","sources":["../src/untrustedContent.ts"],"names":[],"mappings":"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"}