Skip to content

Commit eb9301d

Browse files
committed
Move getSupportedElicitationModes into client (not shared)
1 parent e4c28be commit eb9301d

File tree

4 files changed

+85
-94
lines changed

4 files changed

+85
-94
lines changed

src/client/index.test.ts

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* eslint-disable @typescript-eslint/no-unused-vars */
22
/* eslint-disable no-constant-binary-expression */
33
/* eslint-disable @typescript-eslint/no-unused-expressions */
4-
import { Client } from './index.js';
4+
import { Client, getSupportedElicitationModes } from './index.js';
55
import { z } from 'zod';
66
import {
77
RequestSchema,
@@ -1543,3 +1543,59 @@ describe('outputSchema validation', () => {
15431543
);
15441544
});
15451545
});
1546+
1547+
describe('getSupportedElicitationModes', () => {
1548+
test('should support nothing when capabilities are undefined', () => {
1549+
const result = getSupportedElicitationModes(undefined);
1550+
expect(result.supportsFormMode).toBe(false);
1551+
expect(result.supportsUrlMode).toBe(false);
1552+
});
1553+
1554+
test('should default to form mode when capabilities are an empty object', () => {
1555+
const result = getSupportedElicitationModes({});
1556+
expect(result.supportsFormMode).toBe(true);
1557+
expect(result.supportsUrlMode).toBe(false);
1558+
});
1559+
1560+
test('should support form mode when form is explicitly declared', () => {
1561+
const result = getSupportedElicitationModes({ form: {} });
1562+
expect(result.supportsFormMode).toBe(true);
1563+
expect(result.supportsUrlMode).toBe(false);
1564+
});
1565+
1566+
test('should support url mode when url is explicitly declared', () => {
1567+
const result = getSupportedElicitationModes({ url: {} });
1568+
expect(result.supportsFormMode).toBe(false);
1569+
expect(result.supportsUrlMode).toBe(true);
1570+
});
1571+
1572+
test('should support both modes when both are explicitly declared', () => {
1573+
const result = getSupportedElicitationModes({ form: {}, url: {} });
1574+
expect(result.supportsFormMode).toBe(true);
1575+
expect(result.supportsUrlMode).toBe(true);
1576+
});
1577+
1578+
test('should support form mode when only applyDefaults is present', () => {
1579+
const result = getSupportedElicitationModes({ applyDefaults: true });
1580+
expect(result.supportsFormMode).toBe(true);
1581+
expect(result.supportsUrlMode).toBe(false);
1582+
});
1583+
1584+
test('should support form mode when applyDefaults and form are present', () => {
1585+
const result = getSupportedElicitationModes({ applyDefaults: true, form: {} });
1586+
expect(result.supportsFormMode).toBe(true);
1587+
expect(result.supportsUrlMode).toBe(false);
1588+
});
1589+
1590+
test('should support url mode when applyDefaults and url are present', () => {
1591+
const result = getSupportedElicitationModes({ applyDefaults: true, url: {} });
1592+
expect(result.supportsFormMode).toBe(false);
1593+
expect(result.supportsUrlMode).toBe(true);
1594+
});
1595+
1596+
test('should support both modes when applyDefaults, form, and url are present', () => {
1597+
const result = getSupportedElicitationModes({ applyDefaults: true, form: {}, url: {} });
1598+
expect(result.supportsFormMode).toBe(true);
1599+
expect(result.supportsUrlMode).toBe(true);
1600+
});
1601+
});

src/client/index.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { mergeCapabilities, Protocol, type ProtocolOptions, type RequestOptions } from '../shared/protocol.js';
22
import type { Transport } from '../shared/transport.js';
3-
import { getSupportedElicitationModes } from '../shared/elicitation-utils.js';
43
import {
54
type CallToolRequest,
65
CallToolResultSchema,
@@ -86,6 +85,34 @@ function applyElicitationDefaults(schema: JsonSchemaType | undefined, data: unkn
8685
}
8786
}
8887

88+
/**
89+
* Determines which elicitation modes are supported based on declared client capabilities.
90+
*
91+
* According to the spec:
92+
* - An empty elicitation capability object defaults to form mode support (backwards compatibility)
93+
* - URL mode is only supported if explicitly declared
94+
*
95+
* @param capabilities - The client's elicitation capabilities
96+
* @returns An object indicating which modes are supported
97+
*/
98+
export function getSupportedElicitationModes(capabilities: ClientCapabilities['elicitation']): {
99+
supportsFormMode: boolean;
100+
supportsUrlMode: boolean;
101+
} {
102+
if (!capabilities) {
103+
return { supportsFormMode: false, supportsUrlMode: false };
104+
}
105+
106+
const hasFormCapability = Object.prototype.hasOwnProperty.call(capabilities, 'form');
107+
const hasUrlCapability = Object.prototype.hasOwnProperty.call(capabilities, 'url');
108+
109+
// If neither form nor url are explicitly declared, form mode is supported (backwards compatibility)
110+
const supportsFormMode = hasFormCapability || (!hasFormCapability && !hasUrlCapability);
111+
const supportsUrlMode = hasUrlCapability;
112+
113+
return { supportsFormMode, supportsUrlMode };
114+
}
115+
89116
export type ClientOptions = ProtocolOptions & {
90117
/**
91118
* Capabilities to advertise as being supported by this client.

src/shared/elicitation-utils.test.ts

Lines changed: 0 additions & 59 deletions
This file was deleted.

src/shared/elicitation-utils.ts

Lines changed: 0 additions & 33 deletions
This file was deleted.

0 commit comments

Comments
 (0)