Skip to content

Commit 551fbab

Browse files
committed
Allow restricting pages for the automatic context too
1 parent c44b437 commit 551fbab

File tree

6 files changed

+33
-18
lines changed

6 files changed

+33
-18
lines changed

docs/Agents.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,10 @@ ai.agents.journal = {
249249
```
250250

251251
**How it works:**
252-
- If `allowedReadPaths` is set, tools with `readPathParam` can only read pages starting with those prefixes
252+
- If `allowedReadPaths` is set:
253+
- Tools with `readPathParam` can only read pages starting with those prefixes
254+
- Wiki-links in the agent's page body are filtered (only allowed pages included as context)
255+
- Current page content/selection only shown if the page is within allowed paths
253256
- If `allowedWritePaths` is set, tools with `writePathParam` can only write to pages starting with those prefixes
254257
- If not set, no path restrictions apply
255258

docs/Changelog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This page is a brief overview of each version.
77
- Embeddings now include page title and section headers
88
- Benchmark command now shows progress
99
- Reuse SB's theming where possible so that the UI is more consistent
10-
- Add path-based permissions for agents (`allowedReadPaths`, `allowedWritePaths`) to restrict tool access to specific folders
10+
- Add path-based permissions for agents (`allowedReadPaths`, `allowedWritePaths`) to restrict tool access, wiki-link context, and current page context to specific folders
1111

1212
## 0.6.2 (2025-01-05)
1313

src/agents.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { editor, index, lua, space } from "@silverbulletmd/silverbullet/syscalls";
22
import type { AIAgentTemplate, Attachment, LuaToolDefinition } from "./types.ts";
3-
import { luaLongString } from "./utils.ts";
3+
import { isPathAllowed, luaLongString } from "./utils.ts";
44
import { chatSystemPrompt } from "./init.ts";
55

66
/**
@@ -180,6 +180,12 @@ export async function buildAgentSystemPrompt(
180180
console.error("Failed to read agent page:", error);
181181
}
182182

183+
// Filter attachments based on allowedReadPaths
184+
const allowedReadPaths = agent.aiagent.allowedReadPaths;
185+
if (allowedReadPaths?.length) {
186+
attachments = attachments.filter((a) => a.type !== "note" || isPathAllowed(a.name, allowedReadPaths));
187+
}
188+
183189
return { systemPrompt: fullPrompt, attachments };
184190
}
185191

src/chat-panel.ts

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type {
99
Usage,
1010
} from "./types.ts";
1111
import { aiSettings, chatSystemPrompt, currentAIProvider, getSelectedTextModel, initIfNeeded } from "./init.ts";
12-
import { assembleMessagesWithAttachments, cleanMessagesForApi, enrichChatMessages } from "./utils.ts";
12+
import { assembleMessagesWithAttachments, cleanMessagesForApi, enrichChatMessages, isPathAllowed } from "./utils.ts";
1313
import { convertToOpenAITools, discoverTools, runAgenticChat } from "./tools.ts";
1414
import { buildAgentSystemPrompt, discoverAgents, filterToolsForAgent } from "./agents.ts";
1515
import { getModelContextLimit as lookupModelContextLimit } from "./model-metadata.ts";
@@ -170,22 +170,28 @@ export async function startPanelChat(
170170
let contextBlock = "";
171171
try {
172172
const currentPage = await editor.getCurrentPage();
173-
const pageContent = await editor.getText();
174-
const selection = await editor.getSelection();
173+
const allowedReadPaths = currentChatAgent?.aiagent?.allowedReadPaths;
174+
const pageAllowed = isPathAllowed(currentPage, allowedReadPaths);
175175

176176
contextBlock = `Current page: ${currentPage}`;
177177
contextBlock += `\nCurrent date and time: ${new Date().toISOString()}`;
178178
if (currentChatAgent) {
179179
const agentName = currentChatAgent.aiagent.name || currentChatAgent.ref;
180180
contextBlock += `\nActive agent: ${agentName}`;
181181
}
182-
if (selection && selection.text) {
183-
contextBlock += `\nSelected text: "${selection.text}"`;
182+
183+
// Only include selection and content if page is within allowed paths
184+
if (pageAllowed) {
185+
const pageContent = await editor.getText();
186+
const selection = await editor.getSelection();
187+
if (selection && selection.text) {
188+
contextBlock += `\nSelected text: "${selection.text}"`;
189+
}
190+
const truncatedContent = pageContent.length > 4000
191+
? pageContent.substring(0, 4000) + "\n...(truncated)"
192+
: pageContent;
193+
contextBlock += `\n\nPage content:\n${truncatedContent}`;
184194
}
185-
const truncatedContent = pageContent.length > 4000
186-
? pageContent.substring(0, 4000) + "\n...(truncated)"
187-
: pageContent;
188-
contextBlock += `\n\nPage content:\n${truncatedContent}`;
189195
} catch (e) {
190196
console.log("Could not get page context:", e);
191197
}

src/tools.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { asset, clientStore, editor, lua, space } from "@silverbulletmd/silverbullet/syscalls";
2-
import { computeSimpleDiff, type DiffLine } from "./utils.ts";
2+
import { computeSimpleDiff, type DiffLine, isPathAllowed } from "./utils.ts";
33
import type {
44
ChatMessage,
55
ChatResponse,
@@ -11,11 +11,6 @@ import type {
1111
} from "./types.ts";
1212
import { aiSettings } from "./init.ts";
1313

14-
function isPathAllowed(page: string, allowedPaths: string[] | undefined): boolean {
15-
if (!allowedPaths || allowedPaths.length === 0) return true;
16-
return allowedPaths.some((prefix) => page === prefix || page.startsWith(prefix));
17-
}
18-
1914
function validatePathPermission(
2015
tool: LuaToolDefinition,
2116
args: Record<string, unknown>,

src/utils.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ export function log(...args: any[]) {
1414
console.log(...args);
1515
}
1616

17+
export function isPathAllowed(page: string, allowedPaths: string[] | undefined): boolean {
18+
if (!allowedPaths || allowedPaths.length === 0) return true;
19+
return allowedPaths.some((prefix) => page === prefix || page.startsWith(prefix));
20+
}
21+
1722
// Pattern to match ```toolcall\n{json}\n``` fenced code blocks
1823
const TOOL_CALL_WIDGET_PATTERN = /```toolcall\n([\s\S]*?)\n```/g;
1924

0 commit comments

Comments
 (0)