feat(core): track mcp prompt changes
This commit is contained in:
parent
f725b48508
commit
4ef19f2e6a
5 changed files with 210 additions and 6 deletions
|
|
@ -13,6 +13,8 @@ import {
|
|||
ListToolsResultSchema,
|
||||
type LoggingMessageNotification,
|
||||
LoggingMessageNotificationSchema,
|
||||
PromptListChangedNotificationSchema,
|
||||
ResourceListChangedNotificationSchema,
|
||||
ToolListChangedNotificationSchema,
|
||||
ToolSchema,
|
||||
} from "@modelcontextprotocol/sdk/types.js"
|
||||
|
|
@ -79,7 +81,7 @@ export interface CallToolResult {
|
|||
|
||||
export interface LogMessage {
|
||||
readonly level: LoggingMessageNotification["params"]["level"]
|
||||
readonly logger: LoggingMessageNotification["params"]["logger"]
|
||||
readonly logger?: LoggingMessageNotification["params"]["logger"]
|
||||
readonly data: LoggingMessageNotification["params"]["data"]
|
||||
}
|
||||
|
||||
|
|
@ -106,6 +108,10 @@ export interface Connection {
|
|||
readonly onLog: (callback: (message: LogMessage) => void) => void
|
||||
/** Registers a callback fired when the server announces its tool list changed; no-op if unsupported. */
|
||||
readonly onToolsChanged: (callback: () => void) => void
|
||||
/** Registers a callback fired when the server announces its prompt list changed; no-op if unsupported. */
|
||||
readonly onPromptsChanged: (callback: () => void) => void
|
||||
/** Registers a callback fired when the server announces its resource list changed; no-op if unsupported. */
|
||||
readonly onResourcesChanged: (callback: () => void) => void
|
||||
}
|
||||
|
||||
/** Connects an MCP server; closing the calling scope tears down the transport and any spawned process. */
|
||||
|
|
@ -267,6 +273,14 @@ export const connect = Effect.fnUntraced(function* (
|
|||
if (!client.getServerCapabilities()?.tools?.listChanged) return
|
||||
client.setNotificationHandler(ToolListChangedNotificationSchema, async () => callback())
|
||||
},
|
||||
onPromptsChanged: (callback) => {
|
||||
if (!client.getServerCapabilities()?.prompts?.listChanged) return
|
||||
client.setNotificationHandler(PromptListChangedNotificationSchema, async () => callback())
|
||||
},
|
||||
onResourcesChanged: (callback) => {
|
||||
if (!client.getServerCapabilities()?.resources?.listChanged) return
|
||||
client.setNotificationHandler(ResourceListChangedNotificationSchema, async () => callback())
|
||||
},
|
||||
} satisfies Connection
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -264,7 +264,16 @@ export const layer = Layer.effect(
|
|||
entry.client = undefined
|
||||
entry.tools = undefined
|
||||
entry.status = { status: "failed", error: "Connection closed" }
|
||||
fork(events.publish(McpEvent.ToolsChanged, { server: name }).pipe(Effect.ignore))
|
||||
fork(
|
||||
Effect.all(
|
||||
[
|
||||
events.publish(McpEvent.ToolsChanged, { server: name }),
|
||||
events.publish(McpEvent.PromptsChanged, { server: name }),
|
||||
events.publish(McpEvent.ResourcesChanged, { server: name }),
|
||||
],
|
||||
{ discard: true },
|
||||
).pipe(Effect.ignore),
|
||||
)
|
||||
})
|
||||
connection.onLog((message) => fork(serverLog(name, message).pipe(Effect.ignore)))
|
||||
connection.onToolsChanged(() => {
|
||||
|
|
@ -275,6 +284,12 @@ export const layer = Layer.effect(
|
|||
),
|
||||
)
|
||||
})
|
||||
connection.onPromptsChanged(() => {
|
||||
fork(events.publish(McpEvent.PromptsChanged, { server: name }).pipe(Effect.ignore))
|
||||
})
|
||||
connection.onResourcesChanged(() => {
|
||||
fork(events.publish(McpEvent.ResourcesChanged, { server: name }).pipe(Effect.ignore))
|
||||
})
|
||||
}
|
||||
|
||||
const serverLog = (server: ServerName, message: MCPClient.LogMessage) => {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,20 @@ export const ToolsChanged = Event.define({
|
|||
},
|
||||
})
|
||||
|
||||
export const PromptsChanged = Event.define({
|
||||
type: "mcp.prompts.changed",
|
||||
schema: {
|
||||
server: Schema.String,
|
||||
},
|
||||
})
|
||||
|
||||
export const ResourcesChanged = Event.define({
|
||||
type: "mcp.resources.changed",
|
||||
schema: {
|
||||
server: Schema.String,
|
||||
},
|
||||
})
|
||||
|
||||
export const BrowserOpenFailed = Event.define({
|
||||
type: "mcp.browser.open.failed",
|
||||
schema: {
|
||||
|
|
@ -18,4 +32,4 @@ export const BrowserOpenFailed = Event.define({
|
|||
},
|
||||
})
|
||||
|
||||
export const Definitions = Event.inventory(ToolsChanged, BrowserOpenFailed)
|
||||
export const Definitions = Event.inventory(ToolsChanged, PromptsChanged, ResourcesChanged, BrowserOpenFailed)
|
||||
|
|
|
|||
|
|
@ -279,6 +279,8 @@ import type {
|
|||
V2FsListResponses,
|
||||
V2FsReadErrors,
|
||||
V2FsReadResponses,
|
||||
V2GenerateTextErrors,
|
||||
V2GenerateTextResponses,
|
||||
V2HealthGetErrors,
|
||||
V2HealthGetResponses,
|
||||
V2IntegrationAttemptCancelErrors,
|
||||
|
|
@ -5944,6 +5946,48 @@ export class Model extends HeyApiClient {
|
|||
}
|
||||
}
|
||||
|
||||
export class Generate extends HeyApiClient {
|
||||
/**
|
||||
* Generate text
|
||||
*
|
||||
* Run one stateless model generation at the requested location and return the assistant text. Uses the location's default model when none is specified.
|
||||
*/
|
||||
public text<ThrowOnError extends boolean = false>(
|
||||
parameters?: {
|
||||
location?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
prompt?: string
|
||||
model?: ModelRef
|
||||
},
|
||||
options?: Options<never, ThrowOnError>,
|
||||
) {
|
||||
const params = buildClientParams(
|
||||
[parameters],
|
||||
[
|
||||
{
|
||||
args: [
|
||||
{ in: "query", key: "location" },
|
||||
{ in: "body", key: "prompt" },
|
||||
{ in: "body", key: "model" },
|
||||
],
|
||||
},
|
||||
],
|
||||
)
|
||||
return (options?.client ?? this.client).post<V2GenerateTextResponses, V2GenerateTextErrors, ThrowOnError>({
|
||||
url: "/api/generate",
|
||||
...options,
|
||||
...params,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
...params.headers,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class Provider2 extends HeyApiClient {
|
||||
/**
|
||||
* List providers
|
||||
|
|
@ -7233,6 +7277,11 @@ export class V2 extends HeyApiClient {
|
|||
return (this._model ??= new Model({ client: this.client }))
|
||||
}
|
||||
|
||||
private _generate?: Generate
|
||||
get generate(): Generate {
|
||||
return (this._generate ??= new Generate({ client: this.client }))
|
||||
}
|
||||
|
||||
private _provider?: Provider2
|
||||
get provider(): Provider2 {
|
||||
return (this._provider ??= new Provider2({ client: this.client }))
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ export type Event =
|
|||
| EventTuiToastShow2
|
||||
| EventTuiSessionSelect2
|
||||
| EventMcpToolsChanged
|
||||
| EventMcpPromptsChanged
|
||||
| EventMcpResourcesChanged
|
||||
| EventMcpBrowserOpenFailed
|
||||
| EventCommandExecuted
|
||||
| EventProjectUpdated
|
||||
|
|
@ -646,7 +648,6 @@ export type Prompt = {
|
|||
text: string
|
||||
files?: Array<PromptFileAttachment>
|
||||
agents?: Array<PromptAgentAttachment>
|
||||
system?: string
|
||||
}
|
||||
|
||||
export type Pty = {
|
||||
|
|
@ -1513,6 +1514,20 @@ export type GlobalEvent = {
|
|||
server: string
|
||||
}
|
||||
}
|
||||
| {
|
||||
id: string
|
||||
type: "mcp.prompts.changed"
|
||||
properties: {
|
||||
server: string
|
||||
}
|
||||
}
|
||||
| {
|
||||
id: string
|
||||
type: "mcp.resources.changed"
|
||||
properties: {
|
||||
server: string
|
||||
}
|
||||
}
|
||||
| {
|
||||
id: string
|
||||
type: "mcp.browser.open.failed"
|
||||
|
|
@ -2760,7 +2775,6 @@ export type PromptInput = {
|
|||
text: string
|
||||
files?: Array<PromptInputFileAttachment>
|
||||
agents?: Array<PromptAgentAttachment>
|
||||
system?: string
|
||||
}
|
||||
|
||||
export type ConflictError = {
|
||||
|
|
@ -2834,6 +2848,12 @@ export type SessionMessagesResponse = {
|
|||
}
|
||||
}
|
||||
|
||||
export type GenerateTextResponse = {
|
||||
data: {
|
||||
text: string
|
||||
}
|
||||
}
|
||||
|
||||
export type ProviderNotFoundError = {
|
||||
_tag: "ProviderNotFoundError"
|
||||
providerID: string
|
||||
|
|
@ -2999,6 +3019,8 @@ export type V2Event =
|
|||
| TuiToastShow
|
||||
| TuiSessionSelect
|
||||
| McpToolsChanged
|
||||
| McpPromptsChanged
|
||||
| McpResourcesChanged
|
||||
| McpBrowserOpenFailed
|
||||
| CommandExecuted
|
||||
| ProjectUpdated
|
||||
|
|
@ -4096,7 +4118,6 @@ export type SessionMessageUser = {
|
|||
text: string
|
||||
files?: Array<PromptFileAttachment>
|
||||
agents?: Array<PromptAgentAttachment>
|
||||
system?: string
|
||||
type: "user"
|
||||
}
|
||||
|
||||
|
|
@ -6036,6 +6057,40 @@ export type McpToolsChanged = {
|
|||
}
|
||||
}
|
||||
|
||||
export type McpPromptsChanged = {
|
||||
id: string
|
||||
metadata?: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
type: "mcp.prompts.changed"
|
||||
durable?: {
|
||||
aggregateID: string
|
||||
seq: number
|
||||
version: number
|
||||
}
|
||||
location?: LocationRef
|
||||
data: {
|
||||
server: string
|
||||
}
|
||||
}
|
||||
|
||||
export type McpResourcesChanged = {
|
||||
id: string
|
||||
metadata?: {
|
||||
[key: string]: unknown
|
||||
}
|
||||
type: "mcp.resources.changed"
|
||||
durable?: {
|
||||
aggregateID: string
|
||||
seq: number
|
||||
version: number
|
||||
}
|
||||
location?: LocationRef
|
||||
data: {
|
||||
server: string
|
||||
}
|
||||
}
|
||||
|
||||
export type McpBrowserOpenFailed = {
|
||||
id: string
|
||||
metadata?: {
|
||||
|
|
@ -7117,6 +7172,22 @@ export type EventMcpToolsChanged = {
|
|||
}
|
||||
}
|
||||
|
||||
export type EventMcpPromptsChanged = {
|
||||
id: string
|
||||
type: "mcp.prompts.changed"
|
||||
properties: {
|
||||
server: string
|
||||
}
|
||||
}
|
||||
|
||||
export type EventMcpResourcesChanged = {
|
||||
id: string
|
||||
type: "mcp.resources.changed"
|
||||
properties: {
|
||||
server: string
|
||||
}
|
||||
}
|
||||
|
||||
export type EventMcpBrowserOpenFailed = {
|
||||
id: string
|
||||
type: "mcp.browser.open.failed"
|
||||
|
|
@ -12353,6 +12424,47 @@ export type V2ModelListResponses = {
|
|||
|
||||
export type V2ModelListResponse = V2ModelListResponses[keyof V2ModelListResponses]
|
||||
|
||||
export type V2GenerateTextData = {
|
||||
body: {
|
||||
prompt: string
|
||||
model?: ModelRef
|
||||
}
|
||||
path?: never
|
||||
query?: {
|
||||
location?: {
|
||||
directory?: string
|
||||
workspace?: string
|
||||
}
|
||||
}
|
||||
url: "/api/generate"
|
||||
}
|
||||
|
||||
export type V2GenerateTextErrors = {
|
||||
/**
|
||||
* InvalidRequestError
|
||||
*/
|
||||
400: InvalidRequestError
|
||||
/**
|
||||
* UnauthorizedError
|
||||
*/
|
||||
401: UnauthorizedError
|
||||
/**
|
||||
* ServiceUnavailableError
|
||||
*/
|
||||
503: ServiceUnavailableError
|
||||
}
|
||||
|
||||
export type V2GenerateTextError = V2GenerateTextErrors[keyof V2GenerateTextErrors]
|
||||
|
||||
export type V2GenerateTextResponses = {
|
||||
/**
|
||||
* GenerateTextResponse
|
||||
*/
|
||||
200: GenerateTextResponse
|
||||
}
|
||||
|
||||
export type V2GenerateTextResponse = V2GenerateTextResponses[keyof V2GenerateTextResponses]
|
||||
|
||||
export type V2ProviderListData = {
|
||||
body?: never
|
||||
path?: never
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue