Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions apps/desktop/scripts/browser-runtime.e2e.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -123,19 +123,16 @@ const server = createServer((request, response) => {
<output id="result"></output>
<iframe id="cross-origin-frame" src="\${frameOrigin}/"></iframe>
<script>
document.modelContext = {
getTools: () => [{
name: 'set_result',
title: 'Set result',
description: 'Updates the fixture result.',
inputSchema: JSON.stringify({ type: 'object', properties: { value: { type: 'string' } } }),
}],
executeTool: (_tool, input) => {
const value = JSON.parse(input);
window.__lumeWebMcpModelContext.registerTool({
name: 'set_result',
title: 'Set result',
description: 'Updates the fixture result.',
inputSchema: { type: 'object', properties: { value: { type: 'string' } } },
execute: value => {
document.querySelector('#result').textContent = value.value;
return JSON.stringify({ applied: value.value });
return { applied: value.value };
},
};
});
</script>\`)
})

Expand Down
6 changes: 3 additions & 3 deletions apps/desktop/src/browser-runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3835,7 +3835,7 @@ function normalizeBrowserMethod(method: string): string {
export async function listWebMcpTools(tab: BrowserTab): Promise<{ tools: Array<Record<string, unknown>> }> {
const generation = tab.generation
const value = await browserContents(tab).executeJavaScript(`(async () => {
const modelContext = window.__lumeWebMcpModelContext ?? document.modelContext ?? navigator.modelContext;
const modelContext = document.modelContext ?? window.__lumeWebMcpModelContext ?? navigator.modelContext;
if (!modelContext || typeof modelContext.getTools !== "function") return [];
return (await Promise.resolve(modelContext.getTools())).map((tool) => ({
name: tool.name,
Expand Down Expand Up @@ -3865,15 +3865,15 @@ export async function invokeWebMcpTool(tab: BrowserTab, params: Record<string, u
const timeoutMs = timeoutValue === undefined ? 10_000 : boundedNumber(timeoutValue, 1, 30_000)
const generation = tab.generation
const script = `(() => {
const modelContext = window.__lumeWebMcpModelContext ?? document.modelContext ?? navigator.modelContext;
const modelContext = document.modelContext ?? window.__lumeWebMcpModelContext ?? navigator.modelContext;
if (!modelContext || typeof modelContext.getTools !== "function" || typeof modelContext.executeTool !== "function") {
throw new Error("WebMCP modelContext is unavailable in the current page.");
}
return Promise.resolve(modelContext.getTools())
.then((tools) => {
const tool = tools.find((candidate) => candidate.name === ${JSON.stringify(toolName)});
if (!tool) throw new Error(${JSON.stringify(`WebMCP tool not found: ${toolName}`)});
return modelContext.executeTool(tool, ${JSON.stringify(encodedInput)});
return modelContext.executeTool({ name: tool.name }, ${JSON.stringify(encodedInput)});
})
.then((result) => {
if (result == null || typeof result !== "string") return result ?? null;
Expand Down
2 changes: 1 addition & 1 deletion apps/desktop/src/browser-webmcp-consumer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ describe('invokeWebMcpTool contextIsolation fallback', () => {
test('优先读 window.__lumeWebMcpModelContext.executeTool', async () => {
let captured: { tool?: unknown; input?: unknown } = {}
;(window as unknown as Record<string, unknown>).__lumeWebMcpModelContext = {
getTools: () => [{ name: 'echo' }],
getTools: () => [{ name: 'echo', inputSchema: null, origin: 'https://x.test' }],
executeTool: async (tool: unknown, input: unknown) => {
captured = { tool, input }
return JSON.stringify({ ok: true, input })
Expand Down
Loading