mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:10:44 +00:00
fix(mcp): expose channel payloads in primary content
This commit is contained in:
@@ -48,6 +48,7 @@ Docs: https://docs.openclaw.ai
|
||||
- Control UI: point the Appearance tweakcn browse action and docs at the live tweakcn editor route instead of the removed `/themes` page. Fixes #77048.
|
||||
- Control UI: render Dream Diary prose through the sanitized markdown pipeline, so diary bold/italic/header markdown no longer appears as literal source text. Fixes #62413.
|
||||
- Control UI: render tool results whose output arrives as text-block arrays and give expanded tool output a scrollable block, so read/exec output remains visible in WebChat. Fixes #77054.
|
||||
- MCP: include serialized conversation/message payloads in the primary text content for `conversations_list` and `messages_read`, while preserving `structuredContent` for capable clients. Fixes #77024.
|
||||
- Diagnostics: keep webhook/message OTEL attributes and Prometheus delivery labels low-cardinality and omit raw chat/message IDs from spans, so progress-draft and message-tool modes do not leak high-cardinality messaging identifiers.
|
||||
- Google Meet: stop advertising legacy `mode: "realtime"` to agents and config UIs, while keeping it as a hidden compatibility alias for `mode: "agent"`, so new joins use the STT -> OpenClaw agent -> TTS path instead of selecting the direct realtime voice fallback.
|
||||
- Google Meet: add `chrome.audioBufferBytes` for generated command-pair SoX audio commands and lower the default buffer from SoX's 8192 bytes to 4096 bytes to reduce Chrome talk-back latency.
|
||||
|
||||
@@ -176,6 +176,55 @@ describe("openclaw channel mcp server", () => {
|
||||
);
|
||||
});
|
||||
|
||||
test("serializes conversation and message payloads into MCP primary content", async () => {
|
||||
const mcp = await connectMcpWithoutGateway({ claudeChannelMode: "off" });
|
||||
try {
|
||||
const gatewayRequest = vi.fn(async (method: string) => {
|
||||
if (method === "sessions.list") {
|
||||
return {
|
||||
sessions: [
|
||||
{
|
||||
key: "agent:main:telegram:direct:123",
|
||||
channel: "telegram",
|
||||
deliveryContext: { to: "123" },
|
||||
lastMessagePreview: "hello",
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
if (method === "sessions.get") {
|
||||
return {
|
||||
messages: [
|
||||
{
|
||||
id: "msg-1",
|
||||
role: "assistant",
|
||||
content: [{ type: "text", text: "full transcript text" }],
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
throw new Error(`unexpected gateway method ${method}`);
|
||||
});
|
||||
attachReadyGateway(mcp.bridge, gatewayRequest);
|
||||
|
||||
const conversations = (await mcp.client.callTool({
|
||||
name: "conversations_list",
|
||||
arguments: {},
|
||||
})) as { content?: Array<{ type: string; text?: string }> };
|
||||
expect(conversations.content?.[0]?.text).toContain('"sessionKey"');
|
||||
expect(conversations.content?.[0]?.text).toContain('"lastMessagePreview": "hello"');
|
||||
|
||||
const messages = (await mcp.client.callTool({
|
||||
name: "messages_read",
|
||||
arguments: { session_key: "agent:main:telegram:direct:123" },
|
||||
})) as { content?: Array<{ type: string; text?: string }> };
|
||||
expect(messages.content?.[0]?.text).toContain('"id": "msg-1"');
|
||||
expect(messages.content?.[0]?.text).toContain("full transcript text");
|
||||
} finally {
|
||||
await mcp.close();
|
||||
}
|
||||
});
|
||||
|
||||
test("emits Claude channel and permission notifications", async () => {
|
||||
const sessionKey = "agent:main:main";
|
||||
let mcp: Awaited<ReturnType<typeof connectMcpWithoutGateway>> | null = null;
|
||||
|
||||
@@ -149,6 +149,16 @@ export function summarizeResult(
|
||||
};
|
||||
}
|
||||
|
||||
export function summarizeStructuredResult(
|
||||
label: string,
|
||||
count: number,
|
||||
payload: unknown,
|
||||
): { content: Array<{ type: "text"; text: string }> } {
|
||||
return {
|
||||
content: [{ type: "text", text: `${label}: ${count}\n\n${JSON.stringify(payload, null, 2)}` }],
|
||||
};
|
||||
}
|
||||
|
||||
function resolveConversationChannel(row: SessionRow): string | undefined {
|
||||
return normalizeMessageChannel(
|
||||
toText(row.deliveryContext?.channel) ??
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
extractAttachmentsFromMessage,
|
||||
resolveMessageId,
|
||||
summarizeResult,
|
||||
summarizeStructuredResult,
|
||||
toText,
|
||||
} from "./channel-shared.js";
|
||||
|
||||
@@ -34,7 +35,7 @@ export function registerChannelMcpTools(server: McpServer, bridge: OpenClawChann
|
||||
async (args) => {
|
||||
const conversations = await bridge.listConversations(args);
|
||||
return {
|
||||
...summarizeResult("conversations", conversations.length),
|
||||
...summarizeStructuredResult("conversations", conversations.length, { conversations }),
|
||||
structuredContent: { conversations },
|
||||
};
|
||||
},
|
||||
@@ -69,7 +70,7 @@ export function registerChannelMcpTools(server: McpServer, bridge: OpenClawChann
|
||||
async ({ session_key, limit }) => {
|
||||
const messages = await bridge.readMessages(session_key, limit ?? 20);
|
||||
return {
|
||||
...summarizeResult("messages", messages.length),
|
||||
...summarizeStructuredResult("messages", messages.length, { messages }),
|
||||
structuredContent: { messages },
|
||||
};
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user