mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-25 20:05:46 -06:00
73a9eed95b
* feat(audit): carry canonical admitted execution context * fix(agents): preserve admitted context across retries * fix(worker): fence legacy launch dialect * test(gateway): track approval temp dirs * fix(plugin-sdk): preserve harness attempt compatibility * fix: close delegated run authority at owner boundaries * fix: internalize delegated authority validators * refactor: split delegated authority proof surfaces * refactor: centralize command admission identity * test: claim runtime tool authority * fix(gateway): keep lifecycle cleanup within static budgets * fix(agents): revalidate harness policy authority * fix(agents): fence awaited approval capability results * test(copilot): supply required harness capability fixtures * fix(agent): preserve scoped embedded run admission * fix(agent): preserve keyless and worker authority * test(agent): bind incomplete-turn authority * docs: preserve execution authority invariants * chore(plugin-sdk): regenerate API baseline * fix(gateway): notify pending claim closure * fix(gateway): revalidate delegated tool authority * fix(plugin-sdk): keep source guard internal * fix: close delegated authority races * fix: revalidate delegated side effects * fix: close harness authority projection gaps * fix: align authority integration types * fix: isolate settled harness finalization * fix: fence recovery identity finalization * fix: preserve committed session worktrees * fix: preserve worker placement agent identity * fix: fence active harness tool work * fix(plugins): restore embedded run admission owner * chore(plugin-sdk): compose integrated surface budgets * fix(copilot): keep finalization attempt type internal * fix(plugins): complete admission owner type imports * test(harness): use settled finalization attempt shape * fix(security): retain exact side-run and approval authority * fix(security): preserve protected authority through terminal sweep * fix(agents): follow moved recovery store owner * fix(ci): align integrated authority owners with gates * fix(plugins): distinguish embedded agent adapter export * chore(plugin-sdk): regenerate API baseline after rolling integration * refactor(gateway): keep session authority within owner budgets * fix(gateway): keep session helpers private * docs(plugin-sdk): name the V2 parameter subpath * chore(integration): reconcile worker and SDK surfaces * docs(plugin-sdk): require the V2 host API floor * chore(plugin-sdk): regenerate after proxy-auth integration
98 lines
3.2 KiB
TypeScript
98 lines
3.2 KiB
TypeScript
import type { EmbeddedRunAttemptParamsV2 as EmbeddedRunAttemptParams } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import type { CodexAppServerClient } from "./client.js";
|
|
import { createCodexNativeMcpAppResultDetailsPreparer } from "./native-mcp-app.js";
|
|
|
|
function createAttempt(enabled = true): EmbeddedRunAttemptParams {
|
|
return {
|
|
sessionId: "session-1",
|
|
sessionKey: "agent:main:dashboard:thread-1",
|
|
workspaceDir: "/tmp/workspace",
|
|
config: enabled ? { mcp: { apps: { enabled: true } } } : {},
|
|
} as EmbeddedRunAttemptParams;
|
|
}
|
|
|
|
describe("Codex native MCP Apps", () => {
|
|
it("uses the active Codex thread for inventory and app resources", async () => {
|
|
const request = vi.fn(async (method: string, params: Record<string, unknown>) => {
|
|
if (method === "mcpServerStatus/list") {
|
|
return {
|
|
data: [
|
|
{
|
|
name: "sample",
|
|
tools: {
|
|
show_options: { description: "Show nearby options", inputSchema: {} },
|
|
show_menu: { description: "Show a restaurant menu", inputSchema: {} },
|
|
},
|
|
},
|
|
],
|
|
};
|
|
}
|
|
if (method === "mcpServer/resource/read") {
|
|
return {
|
|
contents: [
|
|
{
|
|
uri: params.uri,
|
|
mimeType: "text/html;profile=mcp-app",
|
|
text: "<html><body>Sample</body></html>",
|
|
},
|
|
],
|
|
};
|
|
}
|
|
throw new Error(`unexpected request: ${method}`);
|
|
});
|
|
const prepare = createCodexNativeMcpAppResultDetailsPreparer({
|
|
client: { request, getInstanceId: () => "client-1" } as unknown as CodexAppServerClient,
|
|
threadId: "thread-1",
|
|
attempt: createAttempt(),
|
|
});
|
|
|
|
const details = await prepare?.({
|
|
id: "call-options",
|
|
type: "mcpToolCall",
|
|
server: "sample",
|
|
tool: "show_options",
|
|
status: "completed",
|
|
appContext: { connectorId: "sample", resourceUri: "ui://sample/options.html" },
|
|
arguments: { limit: 4 },
|
|
result: {
|
|
content: [{ type: "text", text: "Found four restaurants." }],
|
|
structuredContent: { stores: [{ id: "store-1" }] },
|
|
_meta: null,
|
|
},
|
|
} as never);
|
|
expect(details).toMatchObject({
|
|
mcpAppPreview: {
|
|
kind: "canvas",
|
|
view: { id: expect.stringMatching(/^mcp-app-/u), title: "show_options UI" },
|
|
mcpApp: {
|
|
serverName: "sample",
|
|
toolName: "show_options",
|
|
uiResourceUri: "ui://sample/options.html",
|
|
toolCallId: "call-options",
|
|
originSessionKey: "agent:main:dashboard:thread-1",
|
|
},
|
|
},
|
|
});
|
|
expect(request).toHaveBeenCalledWith("mcpServerStatus/list", {
|
|
threadId: "thread-1",
|
|
detail: "full",
|
|
});
|
|
expect(request).toHaveBeenCalledWith("mcpServer/resource/read", {
|
|
threadId: "thread-1",
|
|
server: "sample",
|
|
uri: "ui://sample/options.html",
|
|
});
|
|
});
|
|
|
|
it("does not prepare native app views unless MCP Apps are enabled", () => {
|
|
expect(
|
|
createCodexNativeMcpAppResultDetailsPreparer({
|
|
client: {} as CodexAppServerClient,
|
|
threadId: "thread-1",
|
|
attempt: createAttempt(false),
|
|
}),
|
|
).toBeUndefined();
|
|
});
|
|
});
|