fix(wiki): wiki_disabled agent no longer receives wiki prompt injection

This commit is contained in:
matevip 2026-07-21 18:12:37 +08:00
parent 0ad1371abd
commit a7fdbceb48
2 changed files with 47 additions and 3 deletions

View File

@ -127,13 +127,22 @@ public class WikiKnowledgeBaseService {
* KB just drops out). An agent with no scope rows stays workspace-wide,
* preserving the pre-scoping behavior for every existing agent.
* <p>
* An agent flagged {@code wiki_disabled=true} sees no KBs at all the
* opt-out toggle wins over both workspace visibility and any leftover
* binding rows (the UI clears the rows when the flag is set, so the
* zero-row state must not fall through to "unrestricted").
* <p>
* This is the single choke point for KB access: {@code wiki_list_kbs},
* {@link #findVisibleById}, {@link #findAllByName} and
* {@link #resolvePrimaryKb} all read through here, so narrowing it scopes
* every wiki tool at once.
* {@link #findVisibleById}, {@link #findAllByName},
* {@link #resolvePrimaryKb}, the system-prompt wiki context, and the
* per-turn relevant-page injection all read through here, so narrowing
* it scopes every wiki surface at once.
*/
public List<WikiKnowledgeBaseEntity> listByAgentId(Long agentId) {
AgentEntity agent = getAgentOrNull(agentId);
if (agent != null && Boolean.TRUE.equals(agent.getWikiDisabled())) {
return List.of();
}
List<WikiKnowledgeBaseEntity> workspaceKbs = (agent == null || agent.getWorkspaceId() == null)
? listAll()
: listByWorkspace(agent.getWorkspaceId());

View File

@ -15,6 +15,7 @@ import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ -308,4 +309,38 @@ class WikiKnowledgeBaseServiceTest {
assertThat(service.resolvePrimaryKb(7L).getId()).isEqualTo(300L);
}
// ==================== wiki_disabled opt-out (issue #551) ====================
//
// The "use no knowledge base" toggle sets mate_agent.wiki_disabled=true
// and clears the binding rows. Zero rows normally means "unrestricted",
// so the flag must short-circuit BEFORE the scope fallback otherwise
// the opted-out agent sees every workspace KB again and the system
// prompt keeps injecting wiki content.
@Test
@DisplayName("wiki_disabled hides every KB: list, primary, and by-id lookups all come back empty")
void wikiDisabledHidesAllKbs() {
AgentEntity optedOut = agent(7L, 1L, 100L);
optedOut.setWikiDisabled(true);
when(agentMapper.selectById(7L)).thenReturn(optedOut);
assertThat(service.listByAgentId(7L)).isEmpty();
assertThat(service.resolvePrimaryKb(7L)).isNull();
assertThat(service.findVisibleById(7L, 100L)).isNull();
verify(kbMapper, never()).selectList(any());
}
@Test
@DisplayName("wiki_disabled wins over leftover binding rows")
void wikiDisabledWinsOverLeftoverBindings() {
bindScope(100L);
AgentEntity optedOut = agent(7L, 1L, 100L);
optedOut.setWikiDisabled(true);
when(agentMapper.selectById(7L)).thenReturn(optedOut);
when(kbMapper.selectList(any())).thenReturn(List.of(
kb(100L, null, 1L, "Bound KB")));
assertThat(service.listByAgentId(7L)).isEmpty();
}
}