fix(wechat): bind protected dispatch provider schema
This commit is contained in:
@@ -24,11 +24,16 @@ const MAX_RUN_AGE_MS = 60 * 60 * 1000;
|
||||
const MAX_DISPATCH_CACHE_AGE_MS = 60 * 60 * 1000;
|
||||
const MAX_SECURITY_CACHE_ENTRIES = 4096;
|
||||
const DEFAULT_PERMIT_TTL_MS = 2 * 60 * 1000;
|
||||
const DEFAULT_PROTECTED_DISPATCH_PROVIDER = "chatgpt-supervisor";
|
||||
|
||||
function pluginConfig(event, api) {
|
||||
return event?.context?.pluginConfig ?? api.pluginConfig ?? {};
|
||||
}
|
||||
|
||||
function protectedDispatchProvider(config = {}) {
|
||||
return String(config.protectedDispatchProvider || DEFAULT_PROTECTED_DISPATCH_PROVIDER);
|
||||
}
|
||||
|
||||
function trimToLimit(map, limit = MAX_SECURITY_CACHE_ENTRIES) {
|
||||
while (map.size > limit) map.delete(map.keys().next().value);
|
||||
}
|
||||
@@ -148,7 +153,7 @@ export function authorizeProtectedDispatchCall({ event, ctx = {}, trust, config,
|
||||
const params = eventParams(event);
|
||||
const paramsCheck = protectedDispatchParams(params);
|
||||
if (!paramsCheck.ok) return paramsCheck;
|
||||
const expectedProvider = String(config.protectedDispatchProvider || "chatgpt-supervisor");
|
||||
const expectedProvider = protectedDispatchProvider(config);
|
||||
if (params.provider !== expectedProvider) return { ok: false, code: "provider_mismatch" };
|
||||
const runId = runKey(event, ctx) || trust.runId;
|
||||
const agentId = String(ctx.agentId || trust.agentId || "");
|
||||
@@ -274,6 +279,7 @@ function registerWriterTool(api) {
|
||||
}
|
||||
|
||||
function registerProtectedDispatchTool(api) {
|
||||
const expectedProvider = protectedDispatchProvider(api.pluginConfig);
|
||||
api.registerTool(() => ({
|
||||
name: "aios_protected_dispatch",
|
||||
label: "AIOS Protected Dispatch",
|
||||
@@ -284,7 +290,7 @@ function registerProtectedDispatchTool(api) {
|
||||
required: ["task_id", "provider", "action", "payload", "idempotency_key"],
|
||||
properties: {
|
||||
task_id: { type: "string" },
|
||||
provider: { type: "string" },
|
||||
provider: { type: "string", enum: [expectedProvider] },
|
||||
action: { type: "string" },
|
||||
payload: { type: "object" },
|
||||
idempotency_key: { type: "string" },
|
||||
|
||||
@@ -193,7 +193,9 @@ test("plugin registers the native writer factory and required hook names", () =>
|
||||
assert.equal(tool.name, "aios_evidence_write");
|
||||
assert.equal(tool.label, "AIOS Evidence Writer");
|
||||
assert.equal(tool.executionMode, "sequential");
|
||||
assert.equal(factories.aios_protected_dispatch({}).name, "aios_protected_dispatch");
|
||||
const protectedTool = factories.aios_protected_dispatch({});
|
||||
assert.equal(protectedTool.name, "aios_protected_dispatch");
|
||||
assert.deepEqual(protectedTool.parameters.properties.provider.enum, ["chatgpt-supervisor"]);
|
||||
assert.deepEqual(routes.map((route) => route.path), ["/v1/health", "/v1/execute", "/v1/commands/"]);
|
||||
assert.deepEqual(hooks.sort(), ["agent_end", "before_agent_run", "before_tool_call"]);
|
||||
});
|
||||
@@ -340,6 +342,7 @@ test("explicitly blocked senders and strict conversation mode stay fail-closed",
|
||||
function ownerPluginFixture({
|
||||
mockFailFirstDelivery = false,
|
||||
ownerTtlMs = 60_000,
|
||||
protectedDispatchProvider = "chatgpt-supervisor",
|
||||
trustedSenderIds = ["synthetic-owner", "synthetic-user-a", "synthetic-user-b"],
|
||||
} = {}) {
|
||||
const root = fs.mkdtempSync(path.join(os.tmpdir(), "aios-owner-plugin-"));
|
||||
@@ -362,7 +365,7 @@ function ownerPluginFixture({
|
||||
provenancePublicKeyPath: publicKeyPath,
|
||||
provenanceKeyId: "owner-key-1",
|
||||
tenantId: "v2r1c2-wechat-acceptance",
|
||||
protectedDispatchProvider: "chatgpt-supervisor",
|
||||
protectedDispatchProvider,
|
||||
protectedDispatchTransport: "mock",
|
||||
mockFailFirstDelivery,
|
||||
ownerProvenanceTtlMs: ownerTtlMs,
|
||||
@@ -380,6 +383,12 @@ function ownerPluginFixture({
|
||||
return { root, keys, api, hooks, factories };
|
||||
}
|
||||
|
||||
test("protected dispatch schema constrains provider to the configured value", () => {
|
||||
const fixtureValue = ownerPluginFixture({ protectedDispatchProvider: "configured-supervisor" });
|
||||
const tool = fixtureValue.factories.aios_protected_dispatch({});
|
||||
assert.deepEqual(tool.parameters.properties.provider.enum, ["configured-supervisor"]);
|
||||
});
|
||||
|
||||
async function startSyntheticRun(fixtureValue, { senderId, senderIsOwner, runId }) {
|
||||
const event = {
|
||||
prompt: "synthetic acceptance message", messages: [], accountId: "sandbox",
|
||||
|
||||
Reference in New Issue
Block a user