mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-10-22 10:02:41 +00:00
🎖️ fix: Preserve Endpoint Approval Policy Precedence (#15604)
This commit is contained in:
parent
481c64bed2
commit
3255288f46
3 changed files with 61 additions and 8 deletions
|
|
@ -90,10 +90,22 @@ describe('resolveToolApprovalPolicy', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('keeps the BYOM bypass baseline when the endpoint normally uses default mode', () => {
|
||||
test.each(['default', 'dontAsk', 'bypass'] as const)(
|
||||
'preserves an enabled endpoint %s policy when BYOM is active',
|
||||
(mode) => {
|
||||
const endpoint: TToolApprovalPolicy = {
|
||||
enabled: true,
|
||||
mode,
|
||||
deny: ['dangerous_tool'],
|
||||
};
|
||||
expect(resolveToolApprovalPolicy({ endpoint, attachedCodeEnvironment: true })).toBe(endpoint);
|
||||
},
|
||||
);
|
||||
|
||||
test('uses the BYOM bypass baseline for a configured but inactive endpoint policy', () => {
|
||||
expect(
|
||||
resolveToolApprovalPolicy({
|
||||
endpoint: { enabled: true, mode: 'default', deny: ['dangerous_tool'] },
|
||||
endpoint: { mode: 'dontAsk', deny: ['dangerous_tool'] },
|
||||
attachedCodeEnvironment: true,
|
||||
}),
|
||||
).toEqual({
|
||||
|
|
|
|||
|
|
@ -56,15 +56,20 @@ export interface ToolApprovalPolicyLayers {
|
|||
* - `agent` overrides `mode`/`allow`/`deny`/`ask`/`reason`;
|
||||
* - `skills` may only tighten (add `ask`/`deny`), never loosen.
|
||||
*
|
||||
* The BYOM activation adds only `enabled: true, mode: 'bypass'`; an agent-scoped
|
||||
* hook supplies the risky coding decisions. This avoids prompting managed sibling
|
||||
* agents in the same graph. An explicit endpoint `enabled: false` remains the
|
||||
* administrator emergency override. `agent`/`skills` are accepted but not yet merged.
|
||||
* When no endpoint policy is active, BYOM adds `enabled: true, mode: 'bypass'` and
|
||||
* an agent-scoped hook supplies its coding decisions. An already-enabled endpoint
|
||||
* policy remains the run-wide administrative baseline, including its unmatched-tool
|
||||
* mode. An explicit endpoint `enabled: false` remains the administrator emergency
|
||||
* override. `agent`/`skills` are accepted but not yet merged.
|
||||
*/
|
||||
export function resolveToolApprovalPolicy(
|
||||
layers: ToolApprovalPolicyLayers,
|
||||
): TToolApprovalPolicy | undefined {
|
||||
if (layers.attachedCodeEnvironment === true && layers.endpoint?.enabled !== false) {
|
||||
if (
|
||||
layers.attachedCodeEnvironment === true &&
|
||||
layers.endpoint?.enabled !== true &&
|
||||
layers.endpoint?.enabled !== false
|
||||
) {
|
||||
return {
|
||||
...layers.endpoint,
|
||||
enabled: true,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
import { HookRegistry } from '@librechat/agents';
|
||||
import { HookRegistry, executeHooks } from '@librechat/agents';
|
||||
import { registerToolApprovalHook, clearToolApprovalHooks } from './hooks';
|
||||
import { createAttachedCodeEnvironmentPolicyHook } from './byom';
|
||||
import { resolveToolApprovalPolicy } from './policy';
|
||||
import { buildHITLRunWiring } from './runtime';
|
||||
|
||||
describe('buildHITLRunWiring', () => {
|
||||
|
|
@ -53,6 +55,40 @@ describe('buildHITLRunWiring', () => {
|
|||
});
|
||||
expect(wiring?.hooks.getMatchers('PreToolUse')).toHaveLength(1);
|
||||
});
|
||||
|
||||
test.each([
|
||||
['default', 'ask'],
|
||||
['dontAsk', 'deny'],
|
||||
] as const)(
|
||||
'keeps the enabled endpoint %s fallback for unrelated tools in BYOM runs',
|
||||
async (mode, expectedDecision) => {
|
||||
const policy = resolveToolApprovalPolicy({
|
||||
endpoint: { enabled: true, mode },
|
||||
attachedCodeEnvironment: true,
|
||||
});
|
||||
const wiring = buildHITLRunWiring(
|
||||
policy,
|
||||
{},
|
||||
[],
|
||||
[{ hook: createAttachedCodeEnvironmentPolicyHook(new Set(['attached-agent'])) }],
|
||||
);
|
||||
|
||||
const result = await executeHooks({
|
||||
registry: wiring?.hooks as HookRegistry,
|
||||
matchQuery: 'mcp:github:create_issue',
|
||||
input: {
|
||||
hook_event_name: 'PreToolUse',
|
||||
runId: 'run-byom-policy',
|
||||
toolName: 'mcp:github:create_issue',
|
||||
toolInput: {},
|
||||
toolUseId: 'tool-unrelated',
|
||||
executingAgentId: 'attached-agent',
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.decision).toBe(expectedDecision);
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('buildHITLRunWiring host-hook composition', () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue