Handle mentioned apps via smart context (#1412)
<!-- CURSOR_SUMMARY -->
> [!NOTE]
> Send mentioned apps (names + files) to the engine through
dyad_options, omit inline other-apps prefix when engine is enabled, and
adjust e2e to snapshot request payload.
>
> - **Engine/Backend**:
> - Pass mentioned apps to engine via
`providerOptions['dyad-engine'].dyadMentionedApps` and forward as
`dyad_options.mentioned_apps` in `llm_engine_provider`.
> - Gate inline other-apps context: only include `otherCodebasePrefix`
when `isEngineEnabled` is false.
> - Enhance `extractMentionedAppsCodebases` to return `files` alongside
`codebaseInfo`.
> - **Tests**:
> - e2e: change `mention app (with pro)` snapshot to
`snapshotServerDump("request")` and update snapshot to assert request
payload contents.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7ddddf6c16c53cd36b4c7e4ec6a57da0616d1bb0. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
This commit is contained in:
@@ -17,5 +17,5 @@ test("mention app (with pro)", async ({ po }) => {
|
|||||||
await po.goToAppsTab();
|
await po.goToAppsTab();
|
||||||
await po.sendPrompt("[dump] @app:minimal-with-ai-rules hi");
|
await po.sendPrompt("[dump] @app:minimal-with-ai-rules hi");
|
||||||
|
|
||||||
await po.snapshotServerDump("all-messages");
|
await po.snapshotServerDump("request");
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -630,18 +630,21 @@ This conversation includes one or more image attachments. When the user uploads
|
|||||||
},
|
},
|
||||||
] as const);
|
] as const);
|
||||||
|
|
||||||
const otherCodebasePrefix = otherAppsCodebaseInfo
|
// If engine is enabled, we will send the other apps codebase info to the engine
|
||||||
? ([
|
// and process it with smart context.
|
||||||
{
|
const otherCodebasePrefix =
|
||||||
role: "user",
|
otherAppsCodebaseInfo && !isEngineEnabled
|
||||||
content: createOtherAppsCodebasePrompt(otherAppsCodebaseInfo),
|
? ([
|
||||||
},
|
{
|
||||||
{
|
role: "user",
|
||||||
role: "assistant",
|
content: createOtherAppsCodebasePrompt(otherAppsCodebaseInfo),
|
||||||
content: "OK.",
|
},
|
||||||
},
|
{
|
||||||
] as const)
|
role: "assistant",
|
||||||
: [];
|
content: "OK.",
|
||||||
|
},
|
||||||
|
] as const)
|
||||||
|
: [];
|
||||||
|
|
||||||
const limitedHistoryChatMessages = limitedMessageHistory.map((msg) => ({
|
const limitedHistoryChatMessages = limitedMessageHistory.map((msg) => ({
|
||||||
role: msg.role as "user" | "assistant" | "system",
|
role: msg.role as "user" | "assistant" | "system",
|
||||||
@@ -720,6 +723,12 @@ This conversation includes one or more image attachments. When the user uploads
|
|||||||
"dyad-engine": {
|
"dyad-engine": {
|
||||||
dyadRequestId,
|
dyadRequestId,
|
||||||
dyadDisableFiles,
|
dyadDisableFiles,
|
||||||
|
dyadMentionedApps: mentionedAppsCodebases.map(
|
||||||
|
({ files, appName }) => ({
|
||||||
|
appName,
|
||||||
|
files,
|
||||||
|
}),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
"dyad-gateway": getExtraProviderOptions(
|
"dyad-gateway": getExtraProviderOptions(
|
||||||
modelClient.builtinProviderId,
|
modelClient.builtinProviderId,
|
||||||
|
|||||||
@@ -142,6 +142,10 @@ export function createDyadEngine(
|
|||||||
if ("dyadDisableFiles" in parsedBody) {
|
if ("dyadDisableFiles" in parsedBody) {
|
||||||
delete parsedBody.dyadDisableFiles;
|
delete parsedBody.dyadDisableFiles;
|
||||||
}
|
}
|
||||||
|
const dyadMentionedApps = parsedBody.dyadMentionedApps;
|
||||||
|
if ("dyadMentionedApps" in parsedBody) {
|
||||||
|
delete parsedBody.dyadMentionedApps;
|
||||||
|
}
|
||||||
|
|
||||||
// Track and modify requestId with attempt number
|
// Track and modify requestId with attempt number
|
||||||
let modifiedRequestId = requestId;
|
let modifiedRequestId = requestId;
|
||||||
@@ -161,6 +165,9 @@ export function createDyadEngine(
|
|||||||
smart_context_mode: options.dyadOptions.smartContextMode,
|
smart_context_mode: options.dyadOptions.smartContextMode,
|
||||||
enable_web_search: options.dyadOptions.enableWebSearch,
|
enable_web_search: options.dyadOptions.enableWebSearch,
|
||||||
};
|
};
|
||||||
|
if (dyadMentionedApps?.length) {
|
||||||
|
parsedBody.dyad_options.mentioned_apps = dyadMentionedApps;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return modified request with files included and requestId in headers
|
// Return modified request with files included and requestId in headers
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { db } from "../../db";
|
import { db } from "../../db";
|
||||||
import { getDyadAppPath } from "../../paths/paths";
|
import { getDyadAppPath } from "../../paths/paths";
|
||||||
import { extractCodebase } from "../../utils/codebase";
|
import { CodebaseFile, extractCodebase } from "../../utils/codebase";
|
||||||
import { validateChatContext } from "../utils/context_paths_utils";
|
import { validateChatContext } from "../utils/context_paths_utils";
|
||||||
import log from "electron-log";
|
import log from "electron-log";
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ const logger = log.scope("mention_apps");
|
|||||||
export async function extractMentionedAppsCodebases(
|
export async function extractMentionedAppsCodebases(
|
||||||
mentionedAppNames: string[],
|
mentionedAppNames: string[],
|
||||||
excludeCurrentAppId?: number,
|
excludeCurrentAppId?: number,
|
||||||
): Promise<{ appName: string; codebaseInfo: string }[]> {
|
): Promise<{ appName: string; codebaseInfo: string; files: CodebaseFile[] }[]> {
|
||||||
if (mentionedAppNames.length === 0) {
|
if (mentionedAppNames.length === 0) {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
@@ -25,14 +25,18 @@ export async function extractMentionedAppsCodebases(
|
|||||||
) && app.id !== excludeCurrentAppId,
|
) && app.id !== excludeCurrentAppId,
|
||||||
);
|
);
|
||||||
|
|
||||||
const results: { appName: string; codebaseInfo: string }[] = [];
|
const results: {
|
||||||
|
appName: string;
|
||||||
|
codebaseInfo: string;
|
||||||
|
files: CodebaseFile[];
|
||||||
|
}[] = [];
|
||||||
|
|
||||||
for (const app of mentionedApps) {
|
for (const app of mentionedApps) {
|
||||||
try {
|
try {
|
||||||
const appPath = getDyadAppPath(app.path);
|
const appPath = getDyadAppPath(app.path);
|
||||||
const chatContext = validateChatContext(app.chatContext);
|
const chatContext = validateChatContext(app.chatContext);
|
||||||
|
|
||||||
const { formattedOutput } = await extractCodebase({
|
const { formattedOutput, files } = await extractCodebase({
|
||||||
appPath,
|
appPath,
|
||||||
chatContext,
|
chatContext,
|
||||||
});
|
});
|
||||||
@@ -40,6 +44,7 @@ export async function extractMentionedAppsCodebases(
|
|||||||
results.push({
|
results.push({
|
||||||
appName: app.name,
|
appName: app.name,
|
||||||
codebaseInfo: formattedOutput,
|
codebaseInfo: formattedOutput,
|
||||||
|
files,
|
||||||
});
|
});
|
||||||
|
|
||||||
logger.log(`Extracted codebase for mentioned app: ${app.name}`);
|
logger.log(`Extracted codebase for mentioned app: ${app.name}`);
|
||||||
|
|||||||
Reference in New Issue
Block a user