fix(core): keep mcp elicitations alive
This commit is contained in:
parent
12d9f4b29b
commit
2c5cc78cd5
1 changed files with 26 additions and 3 deletions
|
|
@ -32,6 +32,7 @@ import { InstallationVersion } from "../installation/version"
|
||||||
|
|
||||||
const DEFAULT_STARTUP_TIMEOUT = 30_000
|
const DEFAULT_STARTUP_TIMEOUT = 30_000
|
||||||
const DEFAULT_REQUEST_TIMEOUT = 30_000
|
const DEFAULT_REQUEST_TIMEOUT = 30_000
|
||||||
|
const ELICITATION_PROGRESS_INTERVAL = 10_000
|
||||||
|
|
||||||
type Transport = StdioClientTransport | StreamableHTTPClientTransport
|
type Transport = StdioClientTransport | StreamableHTTPClientTransport
|
||||||
|
|
||||||
|
|
@ -182,9 +183,31 @@ export const connect = Effect.fnUntraced(function* (
|
||||||
Promise.resolve({ roots: [{ uri: pathToFileURL(directory).href }] }),
|
Promise.resolve({ roots: [{ uri: pathToFileURL(directory).href }] }),
|
||||||
)
|
)
|
||||||
if (elicitation) {
|
if (elicitation) {
|
||||||
client.setRequestHandler(ElicitRequestSchema, (request, extra) =>
|
client.setRequestHandler(ElicitRequestSchema, async (request, extra) => {
|
||||||
Effect.runPromise(elicitation.create({ server, params: request.params, signal: extra.signal })),
|
const progressToken = extra._meta?.progressToken
|
||||||
)
|
const started = Date.now()
|
||||||
|
// Human input can exceed the server's request timeout; progress keeps cooperative callers alive.
|
||||||
|
const sendProgress = () => {
|
||||||
|
if (progressToken === undefined) return
|
||||||
|
void extra
|
||||||
|
.sendNotification({
|
||||||
|
method: "notifications/progress",
|
||||||
|
params: {
|
||||||
|
progressToken,
|
||||||
|
progress: Date.now() - started,
|
||||||
|
message: "Waiting for user response",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.catch(() => undefined)
|
||||||
|
}
|
||||||
|
const interval = progressToken === undefined ? undefined : setInterval(sendProgress, ELICITATION_PROGRESS_INTERVAL)
|
||||||
|
sendProgress()
|
||||||
|
try {
|
||||||
|
return await Effect.runPromise(elicitation.create({ server, params: request.params, signal: extra.signal }))
|
||||||
|
} finally {
|
||||||
|
if (interval !== undefined) clearInterval(interval)
|
||||||
|
}
|
||||||
|
})
|
||||||
client.setNotificationHandler(ElicitationCompleteNotificationSchema, (notification) =>
|
client.setNotificationHandler(ElicitationCompleteNotificationSchema, (notification) =>
|
||||||
Effect.runPromise(elicitation.complete({ server, elicitationID: notification.params.elicitationId })),
|
Effect.runPromise(elicitation.complete({ server, elicitationID: notification.params.elicitationId })),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue