The current page id was only injected as text in the system prompt, which a proxy (CLIProxyAPI) can rewrite/truncate, so the agent could lose track of 'this page'. Add a getCurrentPage tool the model can call to read the open page (id + title) from the server-side request context (forUser now takes openedPage, threaded from body.openPage — the same value used for the system prompt). The inline system-prompt line is kept as belt-and-suspenders. Reads/writes still go through the CASL-enforced page tools by id, so this is strictly not worse than the existing prompt hint — just delivered over a channel the proxy can't mangle. User-approved on the issue. Completes #43 together with the hardness-1 fix. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -257,6 +257,9 @@ export class AiChatService {
|
||||
sessionId,
|
||||
workspace.id,
|
||||
chatId,
|
||||
// Same open-page value used by the system prompt above; exposed to the
|
||||
// model via getCurrentPage so page identity survives prompt mangling.
|
||||
body.openPage,
|
||||
);
|
||||
|
||||
// Merge in admin-configured external MCP tools (web search, etc.; §6.8).
|
||||
|
||||
@@ -50,6 +50,11 @@ export class AiChatToolsService {
|
||||
// agent write (REST + collab) records { actor:'agent', aiChatId } off a
|
||||
// SIGNED claim — non-spoofable, never a client body field (§6.5/§6.6).
|
||||
aiChatId: string,
|
||||
// The page the user currently has open (from the request context), exposed
|
||||
// to the model via getCurrentPage. Optional and last so existing callers
|
||||
// keep compiling. Kept proxy-robust: the model can CALL for the current
|
||||
// page instead of relying on it surviving in the system prompt text.
|
||||
openedPage?: { id?: string; title?: string } | null,
|
||||
): Promise<Record<string, Tool>> {
|
||||
const apiUrl =
|
||||
process.env.MCP_DOCMOST_API_URL ||
|
||||
@@ -210,6 +215,23 @@ export class AiChatToolsService {
|
||||
},
|
||||
}),
|
||||
|
||||
getCurrentPage: tool({
|
||||
description:
|
||||
'Return the page the user is currently viewing — i.e. what "this page", ' +
|
||||
'"the current page", or "here" refers to. Returns the page id and title, ' +
|
||||
'or null if the user is not currently on a page. Call this first whenever ' +
|
||||
'the user refers to the current page without giving an explicit id.',
|
||||
inputSchema: z.object({}),
|
||||
execute: async () => {
|
||||
if (!openedPage?.id) {
|
||||
return { page: null };
|
||||
}
|
||||
return {
|
||||
page: { id: openedPage.id, title: openedPage.title ?? '' },
|
||||
};
|
||||
},
|
||||
}),
|
||||
|
||||
getPage: tool({
|
||||
description:
|
||||
'Fetch a single page as Markdown by its page id. Returns the page ' +
|
||||
|
||||
Reference in New Issue
Block a user