mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-18 00:03:11 +00:00
* Revert "docs: agent editor comments describe runs as the caller" This reverts commitd94919c9fe. * Revert "refactor: agents run as the caller, with a note on what a shared one needs" This reverts commit0748a2fb51. * fix: a run as an identity continues only the caller's own conversation Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: an agent run as its identity takes only attachments its caller may read Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: the resource editor keeps an agent's identity on an admin's save Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: regenerate workspace tool schemas for preserve_on_behalf_of Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: the rust client sets preserve_on_behalf_of on resource writes Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat: agents run on behalf of their identity only when they opt in Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: an agent holds an identity only while it runs on behalf of it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: reduce the agent identity migration to clearing untrusted keys Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: refuse decoded variable references in inputs to an agent run as its identity Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: user renames and offboarding re-point an agent's identity Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: refuse model-written tool arguments that the tool's job would interpolate Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * chore: agent on-behalf-of migration after main's Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix: the agent identity migration also clears trashed agents Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
58 lines
2.1 KiB
TypeScript
58 lines
2.1 KiB
TypeScript
/**
|
|
* An agent's run-as identity lives in its value, which the pull leaves out. A
|
|
* push must neither see that gap as a change nor let the file pick who the
|
|
* agent runs as: only the deployed identity is claimed back, and only by a
|
|
* pusher the backend lets keep it.
|
|
*/
|
|
|
|
import { expect, test } from "bun:test";
|
|
import { isSuperset } from "../src/types.ts";
|
|
import { agentOnBehalfOf } from "../src/commands/resource/resource.ts";
|
|
|
|
const ctx = (userIsAdminOrDeployer: boolean) => ({
|
|
userCache: new Map(),
|
|
userIsAdminOrDeployer,
|
|
userEmail: "me@x.dev",
|
|
});
|
|
|
|
function agents(localObo?: string) {
|
|
const deployed = {
|
|
resource_type: "ai_agent",
|
|
value: { system_prompt: "hi", on_behalf_of: "u/bob" },
|
|
} as any;
|
|
const local = {
|
|
resource_type: "ai_agent",
|
|
value: { system_prompt: "hi", ...(localObo ? { on_behalf_of: localObo } : {}) },
|
|
} as any;
|
|
return { deployed, local };
|
|
}
|
|
|
|
test("an unchanged agent still compares equal to the deployed one", () => {
|
|
const { deployed, local } = agents();
|
|
agentOnBehalfOf(deployed, local, ctx(true));
|
|
expect(isSuperset(local, deployed)).toBe(true);
|
|
});
|
|
|
|
test("an admin or deployer claims the deployed identity, never the file's", () => {
|
|
const { deployed, local } = agents("u/admin");
|
|
expect(agentOnBehalfOf(deployed, local, ctx(true))).toBe("u/bob");
|
|
expect(local.value.on_behalf_of).toBeUndefined();
|
|
});
|
|
|
|
test("anyone else claims nothing", () => {
|
|
const { deployed, local } = agents("u/bob");
|
|
expect(agentOnBehalfOf(deployed, local, ctx(false))).toBeUndefined();
|
|
expect(agentOnBehalfOf(agents().deployed, agents().local, undefined)).toBeUndefined();
|
|
expect(local.value.on_behalf_of).toBeUndefined();
|
|
});
|
|
|
|
test("other resources are left alone, an agent retyped into one included", () => {
|
|
for (const deployedType of ["json", "ai_agent"]) {
|
|
const deployed = { resource_type: deployedType, value: { on_behalf_of: "u/bob" } } as any;
|
|
const local = { resource_type: "json", value: { on_behalf_of: "u/x" } } as any;
|
|
expect(agentOnBehalfOf(deployed, local, ctx(true))).toBeUndefined();
|
|
expect(local.value.on_behalf_of).toBe("u/x");
|
|
expect(deployed.value.on_behalf_of).toBe("u/bob");
|
|
}
|
|
});
|