* feat: MCP app sampling support via stock SDK types Alternative to #477. Instead of forking a stripped-down sampling schema, this reuses the stock `CreateMessageRequest` / `CreateMessageResult` / `CreateMessageResultWithTools` types from `@modelcontextprotocol/sdk` directly — same pattern already used for `tools/call`. - Spec: `sampling/createMessage` listed under `### Standard MCP Messages`, `sampling?: { tools?: {} }` added to `HostCapabilities` (mirrors MCP `ClientCapabilities.sampling` shape for easy pass-through). - SDK: `App.createSamplingMessage()` with overloads that narrow the return type based on whether `params.tools` is set; `AppBridge.oncreatesamplingmessage` setter; `CreateMessageRequest`/`CreateMessageResult*` added to the `AppRequest`/`AppResult` unions. - Picks up SEP-1577 tool-calling support (`tools`, `toolChoice`, `tool_use` content blocks, `stopReason: "toolUse"`, array content) for free — unblocks the "nested agents" use case motivated by the original PR. https://claude.ai/code/session_01ENGWTtsfcyP4S6fTWtUMAh * feat(app): guard createSamplingMessage before handshake completes --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
parent
4f89a6f8ea
commit
926dcb4fe9
1 changed files with 323 additions and 1 deletions
|
|
@ -737,6 +737,43 @@ describe("App <-> AppBridge integration", () => {
|
|||
expect(result.content).toEqual(resultContent);
|
||||
});
|
||||
|
||||
it("oncreatesamplingmessage setter registers handler for sampling/createMessage requests", async () => {
|
||||
// Re-create bridge with sampling capability so App's capability check passes
|
||||
bridge = new AppBridge(null, testHostInfo, {
|
||||
...testHostCapabilities,
|
||||
sampling: { tools: {} },
|
||||
});
|
||||
|
||||
const receivedParams: unknown[] = [];
|
||||
bridge.oncreatesamplingmessage = async (params) => {
|
||||
receivedParams.push(params);
|
||||
return {
|
||||
role: "assistant",
|
||||
content: { type: "text", text: "Hello from the model" },
|
||||
model: "test-model",
|
||||
stopReason: "endTurn",
|
||||
};
|
||||
};
|
||||
|
||||
await bridge.connect(bridgeTransport);
|
||||
await app.connect(appTransport);
|
||||
|
||||
expect(app.getHostCapabilities()?.sampling?.tools).toEqual({});
|
||||
|
||||
const result = await app.createSamplingMessage({
|
||||
messages: [{ role: "user", content: { type: "text", text: "Hi" } }],
|
||||
maxTokens: 50,
|
||||
});
|
||||
|
||||
expect(receivedParams).toHaveLength(1);
|
||||
expect(receivedParams[0]).toMatchObject({ maxTokens: 50 });
|
||||
expect(result.model).toEqual("test-model");
|
||||
expect(result.content).toEqual({
|
||||
type: "text",
|
||||
text: "Hello from the model",
|
||||
});
|
||||
});
|
||||
|
||||
it("ondownloadfile setter registers handler for ui/download-file requests", async () => {
|
||||
const downloadParams = {
|
||||
contents: [
|
||||
|
|
|
|||
Loading…
Reference in a new issue