feat: add ui/update-model-context (#125)
--------- Co-authored-by: Olivier Chafik <ochafik@anthropic.com>
This commit is contained in:
parent
9acc52cb96
commit
b273279849
8 changed files with 918 additions and 3 deletions
|
|
@ -442,6 +442,82 @@ describe("App <-> AppBridge integration", () => {
|
|||
logger: "TestApp",
|
||||
});
|
||||
});
|
||||
|
||||
it("app.updateModelContext triggers bridge.onupdatemodelcontext and returns result", async () => {
|
||||
const receivedContexts: unknown[] = [];
|
||||
bridge.onupdatemodelcontext = async (params) => {
|
||||
receivedContexts.push(params);
|
||||
return {};
|
||||
};
|
||||
|
||||
await app.connect(appTransport);
|
||||
const result = await app.updateModelContext({
|
||||
content: [{ type: "text", text: "User selected 3 items" }],
|
||||
});
|
||||
|
||||
expect(receivedContexts).toHaveLength(1);
|
||||
expect(receivedContexts[0]).toMatchObject({
|
||||
content: [{ type: "text", text: "User selected 3 items" }],
|
||||
});
|
||||
expect(result).toEqual({});
|
||||
});
|
||||
|
||||
it("app.updateModelContext works with multiple content blocks", async () => {
|
||||
const receivedContexts: unknown[] = [];
|
||||
bridge.onupdatemodelcontext = async (params) => {
|
||||
receivedContexts.push(params);
|
||||
return {};
|
||||
};
|
||||
|
||||
await app.connect(appTransport);
|
||||
const result = await app.updateModelContext({
|
||||
content: [
|
||||
{ type: "text", text: "Filter applied" },
|
||||
{ type: "text", text: "Category: electronics" },
|
||||
],
|
||||
});
|
||||
|
||||
expect(receivedContexts).toHaveLength(1);
|
||||
expect(receivedContexts[0]).toMatchObject({
|
||||
content: [
|
||||
{ type: "text", text: "Filter applied" },
|
||||
{ type: "text", text: "Category: electronics" },
|
||||
],
|
||||
});
|
||||
expect(result).toEqual({});
|
||||
});
|
||||
|
||||
it("app.updateModelContext works with structuredContent", async () => {
|
||||
const receivedContexts: unknown[] = [];
|
||||
bridge.onupdatemodelcontext = async (params) => {
|
||||
receivedContexts.push(params);
|
||||
return {};
|
||||
};
|
||||
|
||||
await app.connect(appTransport);
|
||||
const result = await app.updateModelContext({
|
||||
structuredContent: { selectedItems: 3, total: 150.0, currency: "USD" },
|
||||
});
|
||||
|
||||
expect(receivedContexts).toHaveLength(1);
|
||||
expect(receivedContexts[0]).toMatchObject({
|
||||
structuredContent: { selectedItems: 3, total: 150.0, currency: "USD" },
|
||||
});
|
||||
expect(result).toEqual({});
|
||||
});
|
||||
|
||||
it("app.updateModelContext throws when handler throws", async () => {
|
||||
bridge.onupdatemodelcontext = async () => {
|
||||
throw new Error("Context update failed");
|
||||
};
|
||||
|
||||
await app.connect(appTransport);
|
||||
await expect(
|
||||
app.updateModelContext({
|
||||
content: [{ type: "text", text: "Test" }],
|
||||
}),
|
||||
).rejects.toThrow("Context update failed");
|
||||
});
|
||||
});
|
||||
|
||||
describe("App -> Host requests", () => {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import {
|
|||
CallToolRequestSchema,
|
||||
CallToolResult,
|
||||
CallToolResultSchema,
|
||||
EmptyResult,
|
||||
Implementation,
|
||||
ListPromptsRequest,
|
||||
ListPromptsRequestSchema,
|
||||
|
|
@ -51,6 +52,8 @@ import {
|
|||
type McpUiToolResultNotification,
|
||||
LATEST_PROTOCOL_VERSION,
|
||||
McpUiAppCapabilities,
|
||||
McpUiUpdateModelContextRequest,
|
||||
McpUiUpdateModelContextRequestSchema,
|
||||
McpUiHostCapabilities,
|
||||
McpUiHostContext,
|
||||
McpUiHostContextChangedNotification,
|
||||
|
|
@ -66,7 +69,6 @@ import {
|
|||
McpUiOpenLinkRequestSchema,
|
||||
McpUiOpenLinkResult,
|
||||
McpUiResourceTeardownRequest,
|
||||
McpUiResourceTeardownResult,
|
||||
McpUiResourceTeardownResultSchema,
|
||||
McpUiSandboxProxyReadyNotification,
|
||||
McpUiSandboxProxyReadyNotificationSchema,
|
||||
|
|
@ -633,6 +635,48 @@ export class AppBridge extends Protocol<
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a handler for model context updates from the Guest UI.
|
||||
*
|
||||
* The Guest UI sends `ui/update-model-context` requests to update the Host's
|
||||
* model context. Each request overwrites the previous context stored by the Guest UI.
|
||||
* Unlike logging messages, context updates are intended to be available to
|
||||
* the model in future turns. Unlike messages, context updates do not trigger follow-ups.
|
||||
*
|
||||
* The host will typically defer sending the context to the model until the
|
||||
* next user message (including `ui/message`), and will only send the last
|
||||
* update received.
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* bridge.onupdatemodelcontext = async ({ content, structuredContent }, extra) => {
|
||||
* // Update the model context with the new snapshot
|
||||
* modelContext = {
|
||||
* type: "app_context",
|
||||
* content,
|
||||
* structuredContent,
|
||||
* timestamp: Date.now()
|
||||
* };
|
||||
* return {};
|
||||
* };
|
||||
* ```
|
||||
*
|
||||
* @see {@link McpUiUpdateModelContextRequest} for the request type
|
||||
*/
|
||||
set onupdatemodelcontext(
|
||||
callback: (
|
||||
params: McpUiUpdateModelContextRequest["params"],
|
||||
extra: RequestHandlerExtra,
|
||||
) => Promise<EmptyResult>,
|
||||
) {
|
||||
this.setRequestHandler(
|
||||
McpUiUpdateModelContextRequestSchema,
|
||||
async (request, extra) => {
|
||||
return callback(request.params, extra);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a handler for tool call requests from the Guest UI.
|
||||
*
|
||||
|
|
|
|||
48
src/app.ts
48
src/app.ts
|
|
@ -9,6 +9,7 @@ import {
|
|||
CallToolRequestSchema,
|
||||
CallToolResult,
|
||||
CallToolResultSchema,
|
||||
EmptyResultSchema,
|
||||
Implementation,
|
||||
ListToolsRequest,
|
||||
ListToolsRequestSchema,
|
||||
|
|
@ -20,6 +21,7 @@ import { PostMessageTransport } from "./message-transport";
|
|||
import {
|
||||
LATEST_PROTOCOL_VERSION,
|
||||
McpUiAppCapabilities,
|
||||
McpUiUpdateModelContextRequest,
|
||||
McpUiHostCapabilities,
|
||||
McpUiHostContext,
|
||||
McpUiHostContextChangedNotification,
|
||||
|
|
@ -809,6 +811,52 @@ export class App extends Protocol<AppRequest, AppNotification, AppResult> {
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the host's model context with app state.
|
||||
*
|
||||
* Unlike `sendLog`, which is for debugging/telemetry, context updates
|
||||
* are intended to be available to the model in future reasoning,
|
||||
* without requiring a follow-up action (like `sendMessage`).
|
||||
*
|
||||
* The host will typically defer sending the context to the model until the
|
||||
* next user message (including `ui/message`), and will only send the last
|
||||
* update received. Each call overwrites any previous context update.
|
||||
*
|
||||
* @param params - Context content and/or structured content
|
||||
* @param options - Request options (timeout, etc.)
|
||||
*
|
||||
* @throws {Error} If the host rejects the context update (e.g., unsupported content type)
|
||||
*
|
||||
* @example Update model context with current app state
|
||||
* ```typescript
|
||||
* await app.updateModelContext({
|
||||
* content: [{ type: "text", text: "User selected 3 items totaling $150.00" }]
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @example Update with structured content
|
||||
* ```typescript
|
||||
* await app.updateModelContext({
|
||||
* structuredContent: { selectedItems: 3, total: 150.00, currency: "USD" }
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @returns Promise that resolves when the context update is acknowledged
|
||||
*/
|
||||
updateModelContext(
|
||||
params: McpUiUpdateModelContextRequest["params"],
|
||||
options?: RequestOptions,
|
||||
) {
|
||||
return this.request(
|
||||
<McpUiUpdateModelContextRequest>{
|
||||
method: "ui/update-model-context",
|
||||
params,
|
||||
},
|
||||
EmptyResultSchema,
|
||||
options,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the host to open an external URL in the default browser.
|
||||
*
|
||||
|
|
|
|||
560
src/generated/schema.json
generated
560
src/generated/schema.json
generated
|
|
@ -162,6 +162,92 @@
|
|||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"updateModelContext": {
|
||||
"description": "Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": {
|
||||
"description": "Host supports text content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"image": {
|
||||
"description": "Host supports image content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"audio": {
|
||||
"description": "Host supports audio content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"resource": {
|
||||
"description": "Host supports resource content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"resourceLink": {
|
||||
"description": "Host supports resource link content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"structuredContent": {
|
||||
"description": "Host supports structured content.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"message": {
|
||||
"description": "Host supports receiving content messages (ui/message) from the Guest UI.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": {
|
||||
"description": "Host supports text content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"image": {
|
||||
"description": "Host supports image content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"audio": {
|
||||
"description": "Host supports audio content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"resource": {
|
||||
"description": "Host supports resource content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"resourceLink": {
|
||||
"description": "Host supports resource link content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"structuredContent": {
|
||||
"description": "Host supports structured content.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
|
@ -2377,6 +2463,92 @@
|
|||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"updateModelContext": {
|
||||
"description": "Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": {
|
||||
"description": "Host supports text content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"image": {
|
||||
"description": "Host supports image content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"audio": {
|
||||
"description": "Host supports audio content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"resource": {
|
||||
"description": "Host supports resource content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"resourceLink": {
|
||||
"description": "Host supports resource link content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"structuredContent": {
|
||||
"description": "Host supports structured content.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"message": {
|
||||
"description": "Host supports receiving content messages (ui/message) from the Guest UI.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": {
|
||||
"description": "Host supports text content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"image": {
|
||||
"description": "Host supports image content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"audio": {
|
||||
"description": "Host supports audio content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"resource": {
|
||||
"description": "Host supports resource content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"resourceLink": {
|
||||
"description": "Host supports resource link content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"structuredContent": {
|
||||
"description": "Host supports structured content.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
|
@ -4631,6 +4803,49 @@
|
|||
],
|
||||
"description": "Style variables for theming MCP apps.\n\nIndividual style keys are optional - hosts may provide any subset of these values.\nValues are strings containing CSS values (colors, sizes, font stacks, etc.).\n\nNote: This type uses `Record<K, string | undefined>` rather than `Partial<Record<K, string>>`\nfor compatibility with Zod schema generation. Both are functionally equivalent for validation."
|
||||
},
|
||||
"McpUiSupportedContentBlockModalities": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"text": {
|
||||
"description": "Host supports text content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"image": {
|
||||
"description": "Host supports image content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"audio": {
|
||||
"description": "Host supports audio content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"resource": {
|
||||
"description": "Host supports resource content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"resourceLink": {
|
||||
"description": "Host supports resource link content blocks.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"structuredContent": {
|
||||
"description": "Host supports structured content.",
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"McpUiTheme": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"anyOf": [
|
||||
|
|
@ -5138,6 +5353,351 @@
|
|||
}
|
||||
],
|
||||
"description": "Tool visibility scope - who can access the tool."
|
||||
},
|
||||
"McpUiUpdateModelContextRequest": {
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"method": {
|
||||
"type": "string",
|
||||
"const": "ui/update-model-context"
|
||||
},
|
||||
"params": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"content": {
|
||||
"description": "Context content blocks (text, image, etc.).",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"const": "text"
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
},
|
||||
"annotations": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"audience": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": ["user", "assistant"]
|
||||
}
|
||||
},
|
||||
"priority": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 1
|
||||
},
|
||||
"lastModified": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"_meta": {
|
||||
"type": "object",
|
||||
"propertyNames": {
|
||||
"type": "string"
|
||||
},
|
||||
"additionalProperties": {}
|
||||
}
|
||||
},
|
||||
"required": ["type", "text"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"const": "image"
|
||||
},
|
||||
"data": {
|
||||
"type": "string"
|
||||
},
|
||||
"mimeType": {
|
||||
"type": "string"
|
||||
},
|
||||
"annotations": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"audience": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": ["user", "assistant"]
|
||||
}
|
||||
},
|
||||
"priority": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 1
|
||||
},
|
||||
"lastModified": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"_meta": {
|
||||
"type": "object",
|
||||
"propertyNames": {
|
||||
"type": "string"
|
||||
},
|
||||
"additionalProperties": {}
|
||||
}
|
||||
},
|
||||
"required": ["type", "data", "mimeType"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"const": "audio"
|
||||
},
|
||||
"data": {
|
||||
"type": "string"
|
||||
},
|
||||
"mimeType": {
|
||||
"type": "string"
|
||||
},
|
||||
"annotations": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"audience": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": ["user", "assistant"]
|
||||
}
|
||||
},
|
||||
"priority": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 1
|
||||
},
|
||||
"lastModified": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"_meta": {
|
||||
"type": "object",
|
||||
"propertyNames": {
|
||||
"type": "string"
|
||||
},
|
||||
"additionalProperties": {}
|
||||
}
|
||||
},
|
||||
"required": ["type", "data", "mimeType"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"icons": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"src": {
|
||||
"type": "string"
|
||||
},
|
||||
"mimeType": {
|
||||
"type": "string"
|
||||
},
|
||||
"sizes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"theme": {
|
||||
"type": "string",
|
||||
"enum": ["light", "dark"]
|
||||
}
|
||||
},
|
||||
"required": ["src"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"uri": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"mimeType": {
|
||||
"type": "string"
|
||||
},
|
||||
"annotations": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"audience": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": ["user", "assistant"]
|
||||
}
|
||||
},
|
||||
"priority": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 1
|
||||
},
|
||||
"lastModified": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"_meta": {
|
||||
"type": "object",
|
||||
"properties": {},
|
||||
"additionalProperties": {}
|
||||
},
|
||||
"type": {
|
||||
"type": "string",
|
||||
"const": "resource_link"
|
||||
}
|
||||
},
|
||||
"required": ["name", "uri", "type"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"const": "resource"
|
||||
},
|
||||
"resource": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"uri": {
|
||||
"type": "string"
|
||||
},
|
||||
"mimeType": {
|
||||
"type": "string"
|
||||
},
|
||||
"_meta": {
|
||||
"type": "object",
|
||||
"propertyNames": {
|
||||
"type": "string"
|
||||
},
|
||||
"additionalProperties": {}
|
||||
},
|
||||
"text": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["uri", "text"],
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"uri": {
|
||||
"type": "string"
|
||||
},
|
||||
"mimeType": {
|
||||
"type": "string"
|
||||
},
|
||||
"_meta": {
|
||||
"type": "object",
|
||||
"propertyNames": {
|
||||
"type": "string"
|
||||
},
|
||||
"additionalProperties": {}
|
||||
},
|
||||
"blob": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": ["uri", "blob"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"annotations": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"audience": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"enum": ["user", "assistant"]
|
||||
}
|
||||
},
|
||||
"priority": {
|
||||
"type": "number",
|
||||
"minimum": 0,
|
||||
"maximum": 1
|
||||
},
|
||||
"lastModified": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"_meta": {
|
||||
"type": "object",
|
||||
"propertyNames": {
|
||||
"type": "string"
|
||||
},
|
||||
"additionalProperties": {}
|
||||
}
|
||||
},
|
||||
"required": ["type", "resource"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"structuredContent": {
|
||||
"description": "Structured content for machine-readable context data.",
|
||||
"type": "object",
|
||||
"propertyNames": {
|
||||
"type": "string"
|
||||
},
|
||||
"additionalProperties": {
|
||||
"description": "Structured content for machine-readable context data."
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"required": ["method", "params"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
20
src/generated/schema.test.ts
generated
20
src/generated/schema.test.ts
generated
|
|
@ -83,6 +83,10 @@ export type McpUiResourceTeardownResultSchemaInferredType = z.infer<
|
|||
typeof generated.McpUiResourceTeardownResultSchema
|
||||
>;
|
||||
|
||||
export type McpUiSupportedContentBlockModalitiesSchemaInferredType = z.infer<
|
||||
typeof generated.McpUiSupportedContentBlockModalitiesSchema
|
||||
>;
|
||||
|
||||
export type McpUiHostCapabilitiesSchemaInferredType = z.infer<
|
||||
typeof generated.McpUiHostCapabilitiesSchema
|
||||
>;
|
||||
|
|
@ -135,6 +139,10 @@ export type McpUiHostContextChangedNotificationSchemaInferredType = z.infer<
|
|||
typeof generated.McpUiHostContextChangedNotificationSchema
|
||||
>;
|
||||
|
||||
export type McpUiUpdateModelContextRequestSchemaInferredType = z.infer<
|
||||
typeof generated.McpUiUpdateModelContextRequestSchema
|
||||
>;
|
||||
|
||||
export type McpUiInitializeRequestSchemaInferredType = z.infer<
|
||||
typeof generated.McpUiInitializeRequestSchema
|
||||
>;
|
||||
|
|
@ -223,6 +231,12 @@ expectType<spec.McpUiResourceTeardownResult>(
|
|||
expectType<McpUiResourceTeardownResultSchemaInferredType>(
|
||||
{} as spec.McpUiResourceTeardownResult,
|
||||
);
|
||||
expectType<spec.McpUiSupportedContentBlockModalities>(
|
||||
{} as McpUiSupportedContentBlockModalitiesSchemaInferredType,
|
||||
);
|
||||
expectType<McpUiSupportedContentBlockModalitiesSchemaInferredType>(
|
||||
{} as spec.McpUiSupportedContentBlockModalities,
|
||||
);
|
||||
expectType<spec.McpUiHostCapabilities>(
|
||||
{} as McpUiHostCapabilitiesSchemaInferredType,
|
||||
);
|
||||
|
|
@ -289,6 +303,12 @@ expectType<spec.McpUiHostContextChangedNotification>(
|
|||
expectType<McpUiHostContextChangedNotificationSchemaInferredType>(
|
||||
{} as spec.McpUiHostContextChangedNotification,
|
||||
);
|
||||
expectType<spec.McpUiUpdateModelContextRequest>(
|
||||
{} as McpUiUpdateModelContextRequestSchemaInferredType,
|
||||
);
|
||||
expectType<McpUiUpdateModelContextRequestSchemaInferredType>(
|
||||
{} as spec.McpUiUpdateModelContextRequest,
|
||||
);
|
||||
expectType<spec.McpUiInitializeRequest>(
|
||||
{} as McpUiInitializeRequestSchemaInferredType,
|
||||
);
|
||||
|
|
|
|||
72
src/generated/schema.ts
generated
72
src/generated/schema.ts
generated
|
|
@ -358,6 +358,36 @@ export const McpUiResourceTeardownResultSchema = z.record(
|
|||
z.unknown(),
|
||||
);
|
||||
|
||||
export const McpUiSupportedContentBlockModalitiesSchema = z.object({
|
||||
/** @description Host supports text content blocks. */
|
||||
text: z.object({}).optional().describe("Host supports text content blocks."),
|
||||
/** @description Host supports image content blocks. */
|
||||
image: z
|
||||
.object({})
|
||||
.optional()
|
||||
.describe("Host supports image content blocks."),
|
||||
/** @description Host supports audio content blocks. */
|
||||
audio: z
|
||||
.object({})
|
||||
.optional()
|
||||
.describe("Host supports audio content blocks."),
|
||||
/** @description Host supports resource content blocks. */
|
||||
resource: z
|
||||
.object({})
|
||||
.optional()
|
||||
.describe("Host supports resource content blocks."),
|
||||
/** @description Host supports resource link content blocks. */
|
||||
resourceLink: z
|
||||
.object({})
|
||||
.optional()
|
||||
.describe("Host supports resource link content blocks."),
|
||||
/** @description Host supports structured content. */
|
||||
structuredContent: z
|
||||
.object({})
|
||||
.optional()
|
||||
.describe("Host supports structured content."),
|
||||
});
|
||||
|
||||
/**
|
||||
* @description Capabilities supported by the host application.
|
||||
* @see {@link McpUiInitializeResult} for the initialization result that includes these capabilities
|
||||
|
|
@ -411,6 +441,15 @@ export const McpUiHostCapabilitiesSchema = z.object({
|
|||
})
|
||||
.optional()
|
||||
.describe("Sandbox configuration applied by the host."),
|
||||
/** @description Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns. */
|
||||
updateModelContext:
|
||||
McpUiSupportedContentBlockModalitiesSchema.optional().describe(
|
||||
"Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns.",
|
||||
),
|
||||
/** @description Host supports receiving content messages (ui/message) from the Guest UI. */
|
||||
message: McpUiSupportedContentBlockModalitiesSchema.optional().describe(
|
||||
"Host supports receiving content messages (ui/message) from the Guest UI.",
|
||||
),
|
||||
});
|
||||
|
||||
/**
|
||||
|
|
@ -714,6 +753,39 @@ export const McpUiHostContextChangedNotificationSchema = z.object({
|
|||
),
|
||||
});
|
||||
|
||||
/**
|
||||
* @description Request to update the agent's context without requiring a follow-up action (Guest UI -> Host).
|
||||
*
|
||||
* Unlike `notifications/message` which is for debugging/logging, this request is intended
|
||||
* to update the Host's model context. Each request overwrites the previous context sent by the Guest UI.
|
||||
* Unlike messages, context updates do not trigger follow-ups.
|
||||
*
|
||||
* The host will typically defer sending the context to the model until the next user message
|
||||
* (including `ui/message`), and will only send the last update received.
|
||||
*
|
||||
* @see {@link app.App.updateModelContext} for the method that sends this request
|
||||
*/
|
||||
export const McpUiUpdateModelContextRequestSchema = z.object({
|
||||
method: z.literal("ui/update-model-context"),
|
||||
params: z.object({
|
||||
/** @description Context content blocks (text, image, etc.). */
|
||||
content: z
|
||||
.array(ContentBlockSchema)
|
||||
.optional()
|
||||
.describe("Context content blocks (text, image, etc.)."),
|
||||
/** @description Structured content for machine-readable context data. */
|
||||
structuredContent: z
|
||||
.record(
|
||||
z.string(),
|
||||
z
|
||||
.unknown()
|
||||
.describe("Structured content for machine-readable context data."),
|
||||
)
|
||||
.optional()
|
||||
.describe("Structured content for machine-readable context data."),
|
||||
}),
|
||||
});
|
||||
|
||||
/**
|
||||
* @description Initialization request sent from Guest UI to Host.
|
||||
* @see {@link app.App.connect} for the method that sends this request
|
||||
|
|
|
|||
|
|
@ -384,6 +384,28 @@ export interface McpUiHostContextChangedNotification {
|
|||
params: McpUiHostContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Request to update the agent's context without requiring a follow-up action (Guest UI -> Host).
|
||||
*
|
||||
* Unlike `notifications/message` which is for debugging/logging, this request is intended
|
||||
* to update the Host's model context. Each request overwrites the previous context sent by the Guest UI.
|
||||
* Unlike messages, context updates do not trigger follow-ups.
|
||||
*
|
||||
* The host will typically defer sending the context to the model until the next user message
|
||||
* (including `ui/message`), and will only send the last update received.
|
||||
*
|
||||
* @see {@link app.App.updateModelContext} for the method that sends this request
|
||||
*/
|
||||
export interface McpUiUpdateModelContextRequest {
|
||||
method: "ui/update-model-context";
|
||||
params: {
|
||||
/** @description Context content blocks (text, image, etc.). */
|
||||
content?: ContentBlock[];
|
||||
/** @description Structured content for machine-readable context data. */
|
||||
structuredContent?: Record<string, unknown>;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Request for graceful shutdown of the Guest UI (Host -> Guest UI).
|
||||
* @see {@link app-bridge.AppBridge.teardownResource} for the host method that sends this
|
||||
|
|
@ -404,6 +426,21 @@ export interface McpUiResourceTeardownResult {
|
|||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export interface McpUiSupportedContentBlockModalities {
|
||||
/** @description Host supports text content blocks. */
|
||||
text?: {};
|
||||
/** @description Host supports image content blocks. */
|
||||
image?: {};
|
||||
/** @description Host supports audio content blocks. */
|
||||
audio?: {};
|
||||
/** @description Host supports resource content blocks. */
|
||||
resource?: {};
|
||||
/** @description Host supports resource link content blocks. */
|
||||
resourceLink?: {};
|
||||
/** @description Host supports structured content. */
|
||||
structuredContent?: {};
|
||||
}
|
||||
|
||||
/**
|
||||
* @description Capabilities supported by the host application.
|
||||
* @see {@link McpUiInitializeResult} for the initialization result that includes these capabilities
|
||||
|
|
@ -432,6 +469,10 @@ export interface McpUiHostCapabilities {
|
|||
/** @description CSP domains approved by the host. */
|
||||
csp?: McpUiResourceCsp;
|
||||
};
|
||||
/** @description Host accepts context updates (ui/update-model-context) to be included in the model's context for future turns. */
|
||||
updateModelContext?: McpUiSupportedContentBlockModalities;
|
||||
/** @description Host supports receiving content messages (ui/message) from the Guest UI. */
|
||||
message?: McpUiSupportedContentBlockModalities;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ export {
|
|||
type McpUiOpenLinkResult,
|
||||
type McpUiMessageRequest,
|
||||
type McpUiMessageResult,
|
||||
type McpUiUpdateModelContextRequest,
|
||||
type McpUiSupportedContentBlockModalities,
|
||||
type McpUiSandboxProxyReadyNotification,
|
||||
type McpUiSandboxResourceReadyNotification,
|
||||
type McpUiSizeChangedNotification,
|
||||
|
|
@ -66,6 +68,7 @@ import type {
|
|||
McpUiInitializeRequest,
|
||||
McpUiOpenLinkRequest,
|
||||
McpUiMessageRequest,
|
||||
McpUiUpdateModelContextRequest,
|
||||
McpUiResourceTeardownRequest,
|
||||
McpUiRequestDisplayModeRequest,
|
||||
McpUiHostContextChangedNotification,
|
||||
|
|
@ -94,6 +97,8 @@ export {
|
|||
McpUiOpenLinkResultSchema,
|
||||
McpUiMessageRequestSchema,
|
||||
McpUiMessageResultSchema,
|
||||
McpUiUpdateModelContextRequestSchema,
|
||||
McpUiSupportedContentBlockModalitiesSchema,
|
||||
McpUiSandboxProxyReadyNotificationSchema,
|
||||
McpUiSandboxResourceReadyNotificationSchema,
|
||||
McpUiSizeChangedNotificationSchema,
|
||||
|
|
@ -153,6 +158,7 @@ export type AppRequest =
|
|||
| McpUiInitializeRequest
|
||||
| McpUiOpenLinkRequest
|
||||
| McpUiMessageRequest
|
||||
| McpUiUpdateModelContextRequest
|
||||
| McpUiResourceTeardownRequest
|
||||
| McpUiRequestDisplayModeRequest
|
||||
| CallToolRequest
|
||||
|
|
|
|||
Loading…
Reference in a new issue