Smart Context: deep (#1527)
<!-- CURSOR_SUMMARY --> > [!NOTE] > Introduce a new "deep" Smart Context mode that supplies versioned files (by commit) to the engine, adds code search rendering, stores source commit hashes, improves search-replace recovery, and updates UI/tests. > > - **Smart Context (deep)**: > - Replace `conservative` with `deep`; limit context to ~200 turns; send `sourceCommitHash` per message. > - Build and pass `versioned_files` (hash-id map + per-message file refs) and `app_id` to engine. > - **DB**: > - Add `messages.source_commit_hash` (+ migration/snapshot). > - **Engine/Processing**: > - Retry Turbo Edits v2: first re-read then fallback to `dyad-write` if search-replace fails. > - Include provider options and versioned files in requests; add `getCurrentCommitHash`/`getFileAtCommit`. > - **UI**: > - Pro mode selector: new `deep` option; tooltips polish. > - Add `DyadCodeSearch` and `DyadCodeSearchResult` components; parser supports new tags. > - **Tests/E2E**: > - New `smart_context_deep` e2e; update snapshots to include `app_id` and deep mode; adjust Playwright timeout. > - Unit tests for versioned codebase context. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit e3d3bffabb2bc6caf52103461f9d6f2d5ad39df8. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This commit is contained in:
@@ -9,23 +9,6 @@ testSkipIfWindows("send message to engine", async ({ po }) => {
|
||||
await po.snapshotMessages({ replaceDumpPath: true });
|
||||
});
|
||||
|
||||
testSkipIfWindows(
|
||||
"send message to engine - smart context conservative",
|
||||
async ({ po }) => {
|
||||
await po.setUpDyadPro();
|
||||
const proModesDialog = await po.openProModesDialog({
|
||||
location: "home-chat-input-container",
|
||||
});
|
||||
await proModesDialog.setSmartContextMode("conservative");
|
||||
await proModesDialog.close();
|
||||
await po.selectModel({ provider: "Google", model: "Gemini 2.5 Pro" });
|
||||
await po.sendPrompt("[dump] tc=turbo-edits");
|
||||
|
||||
await po.snapshotServerDump("request");
|
||||
await po.snapshotMessages({ replaceDumpPath: true });
|
||||
},
|
||||
);
|
||||
|
||||
testSkipIfWindows("send message to engine - openai gpt-5", async ({ po }) => {
|
||||
await po.setUpDyadPro();
|
||||
// By default, it's using auto which points to Flash 2.5 and doesn't
|
||||
|
||||
3
e2e-tests/fixtures/engine/read-index.md
Normal file
3
e2e-tests/fixtures/engine/read-index.md
Normal file
@@ -0,0 +1,3 @@
|
||||
Read the index page:
|
||||
<dyad-read path="src/pages/Index.tsx"></dyad-read>
|
||||
Done.
|
||||
4
e2e-tests/fixtures/engine/update-index-1.md
Normal file
4
e2e-tests/fixtures/engine/update-index-1.md
Normal file
@@ -0,0 +1,4 @@
|
||||
First read
|
||||
<dyad-write path="src/pages/Index.tsx" description="replace file">
|
||||
// this file has been replaced
|
||||
</dyad-write>
|
||||
@@ -71,7 +71,7 @@ class ProModesDialog {
|
||||
public close: () => Promise<void>,
|
||||
) {}
|
||||
|
||||
async setSmartContextMode(mode: "balanced" | "off" | "conservative") {
|
||||
async setSmartContextMode(mode: "balanced" | "off" | "deep") {
|
||||
await this.page
|
||||
.getByTestId("smart-context-selector")
|
||||
.getByRole("button", {
|
||||
|
||||
18
e2e-tests/smart_context_deep.spec.ts
Normal file
18
e2e-tests/smart_context_deep.spec.ts
Normal file
@@ -0,0 +1,18 @@
|
||||
import { testSkipIfWindows } from "./helpers/test_helper";
|
||||
|
||||
testSkipIfWindows("smart context deep - read write read", async ({ po }) => {
|
||||
await po.setUpDyadPro({ autoApprove: true });
|
||||
const proModesDialog = await po.openProModesDialog({
|
||||
location: "home-chat-input-container",
|
||||
});
|
||||
await proModesDialog.setSmartContextMode("deep");
|
||||
await proModesDialog.close();
|
||||
|
||||
await po.sendPrompt("tc=read-index");
|
||||
await po.sendPrompt("tc=update-index-1");
|
||||
await po.sendPrompt("tc=read-index");
|
||||
await po.sendPrompt("[dump]");
|
||||
|
||||
await po.snapshotServerDump("request");
|
||||
await po.snapshotMessages({ replaceDumpPath: true });
|
||||
});
|
||||
@@ -10,6 +10,6 @@ test("switching smart context mode saves the right setting", async ({ po }) => {
|
||||
await po.snapshotSettings();
|
||||
await proModesDialog.setSmartContextMode("off");
|
||||
await po.snapshotSettings();
|
||||
await proModesDialog.setSmartContextMode("conservative");
|
||||
await proModesDialog.setSmartContextMode("deep");
|
||||
await po.snapshotSettings();
|
||||
});
|
||||
|
||||
@@ -99,7 +99,8 @@
|
||||
],
|
||||
"enable_lazy_edits": true,
|
||||
"enable_smart_files_context": true,
|
||||
"smart_context_mode": "balanced"
|
||||
"smart_context_mode": "balanced",
|
||||
"app_id": 1
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
|
||||
@@ -69,7 +69,8 @@
|
||||
],
|
||||
"enable_lazy_edits": true,
|
||||
"enable_smart_files_context": true,
|
||||
"smart_context_mode": "balanced"
|
||||
"smart_context_mode": "balanced",
|
||||
"app_id": 1
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
|
||||
@@ -57,7 +57,8 @@
|
||||
],
|
||||
"enable_lazy_edits": true,
|
||||
"enable_smart_files_context": false,
|
||||
"smart_context_mode": "balanced"
|
||||
"smart_context_mode": "balanced",
|
||||
"app_id": 1
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
|
||||
@@ -115,7 +115,8 @@
|
||||
],
|
||||
"enable_lazy_edits": true,
|
||||
"enable_smart_files_context": false,
|
||||
"smart_context_mode": "balanced"
|
||||
"smart_context_mode": "balanced",
|
||||
"app_id": 1
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
|
||||
@@ -414,7 +414,8 @@
|
||||
],
|
||||
"enable_lazy_edits": true,
|
||||
"enable_smart_files_context": false,
|
||||
"smart_context_mode": "balanced"
|
||||
"smart_context_mode": "balanced",
|
||||
"app_id": 1
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
|
||||
@@ -409,7 +409,8 @@
|
||||
],
|
||||
"enable_lazy_edits": true,
|
||||
"enable_smart_files_context": true,
|
||||
"smart_context_mode": "balanced"
|
||||
"smart_context_mode": "balanced",
|
||||
"app_id": 1
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
|
||||
@@ -409,7 +409,8 @@
|
||||
],
|
||||
"enable_lazy_edits": true,
|
||||
"enable_smart_files_context": true,
|
||||
"smart_context_mode": "balanced"
|
||||
"smart_context_mode": "balanced",
|
||||
"app_id": 1
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,6 +1,10 @@
|
||||
- paragraph: "[dump] tc=turbo-edits"
|
||||
- paragraph: "[[dyad-dump-path=*]]"
|
||||
- button:
|
||||
- img
|
||||
- img
|
||||
- text: less than a minute ago
|
||||
- button "Request ID":
|
||||
- img
|
||||
- button "Retry":
|
||||
- img
|
||||
File diff suppressed because one or more lines are too long
@@ -414,7 +414,8 @@
|
||||
],
|
||||
"enable_lazy_edits": true,
|
||||
"enable_smart_files_context": true,
|
||||
"smart_context_mode": "balanced"
|
||||
"smart_context_mode": "balanced",
|
||||
"app_id": 1
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
|
||||
@@ -414,7 +414,8 @@
|
||||
],
|
||||
"enable_lazy_edits": true,
|
||||
"enable_smart_files_context": true,
|
||||
"smart_context_mode": "balanced"
|
||||
"smart_context_mode": "balanced",
|
||||
"app_id": 1
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
|
||||
@@ -415,6 +415,7 @@
|
||||
"enable_lazy_edits": true,
|
||||
"enable_smart_files_context": true,
|
||||
"smart_context_mode": "balanced",
|
||||
"app_id": 2,
|
||||
"mentioned_apps": [
|
||||
{
|
||||
"appName": "minimal-with-ai-rules",
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
- paragraph: tc=read-index
|
||||
- paragraph: "Read the index page:"
|
||||
- img
|
||||
- text: Index.tsx Read src/pages/Index.tsx
|
||||
- paragraph: Done.
|
||||
- button:
|
||||
- img
|
||||
- img
|
||||
- text: Approved
|
||||
- img
|
||||
- text: less than a minute ago
|
||||
- button "Request ID":
|
||||
- img
|
||||
- paragraph: tc=update-index-1
|
||||
- paragraph: First read
|
||||
- img
|
||||
- text: Index.tsx
|
||||
- button "Edit":
|
||||
- img
|
||||
- img
|
||||
- text: "src/pages/Index.tsx Summary: replace file"
|
||||
- button:
|
||||
- img
|
||||
- img
|
||||
- text: Approved
|
||||
- img
|
||||
- text: less than a minute ago
|
||||
- img
|
||||
- text: wrote 1 file(s)
|
||||
- button "Request ID":
|
||||
- img
|
||||
- paragraph: tc=read-index
|
||||
- paragraph: "Read the index page:"
|
||||
- img
|
||||
- text: Index.tsx Read src/pages/Index.tsx
|
||||
- paragraph: Done.
|
||||
- button:
|
||||
- img
|
||||
- img
|
||||
- text: Approved
|
||||
- img
|
||||
- text: less than a minute ago
|
||||
- button "Request ID":
|
||||
- img
|
||||
- paragraph: "[dump]"
|
||||
- paragraph: "[[dyad-dump-path=*]]"
|
||||
- button:
|
||||
- img
|
||||
- img
|
||||
- text: Approved
|
||||
- img
|
||||
- text: less than a minute ago
|
||||
- button "Request ID":
|
||||
- img
|
||||
- button "Retry":
|
||||
- img
|
||||
File diff suppressed because one or more lines are too long
@@ -19,7 +19,7 @@
|
||||
"lastShownReleaseNotesVersion": "[scrubbed]",
|
||||
"enableProLazyEditsMode": true,
|
||||
"enableProSmartFilesContextMode": true,
|
||||
"proSmartContextOption": "conservative",
|
||||
"proSmartContextOption": "deep",
|
||||
"selectedTemplateId": "react",
|
||||
"selectedChatMode": "build",
|
||||
"enableAutoFixProblems": false,
|
||||
|
||||
@@ -422,7 +422,8 @@
|
||||
],
|
||||
"enable_lazy_edits": true,
|
||||
"enable_smart_files_context": true,
|
||||
"smart_context_mode": "balanced"
|
||||
"smart_context_mode": "balanced",
|
||||
"app_id": 1
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
|
||||
@@ -430,7 +430,8 @@
|
||||
],
|
||||
"enable_lazy_edits": true,
|
||||
"enable_smart_files_context": true,
|
||||
"smart_context_mode": "balanced"
|
||||
"smart_context_mode": "balanced",
|
||||
"app_id": 1
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
|
||||
@@ -438,7 +438,8 @@
|
||||
],
|
||||
"enable_lazy_edits": true,
|
||||
"enable_smart_files_context": true,
|
||||
"smart_context_mode": "balanced"
|
||||
"smart_context_mode": "balanced",
|
||||
"app_id": 1
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
|
||||
@@ -414,7 +414,8 @@
|
||||
],
|
||||
"enable_lazy_edits": false,
|
||||
"enable_smart_files_context": true,
|
||||
"smart_context_mode": "balanced"
|
||||
"smart_context_mode": "balanced",
|
||||
"app_id": 1
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
|
||||
@@ -18,7 +18,15 @@
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "There was an issue with the following `dyad-search-replace` tags. Please fix them by generating the code changes using `dyad-write` tags instead.\n \nFile path: src/pages/Index.tsx\nError: Unable to apply search-replace to file"
|
||||
"content": "There was an issue with the following `dyad-search-replace` tags. Make sure you use `dyad-read` to read the latest version of the file and then trying to do search & replace again.\n \nFile path: src/pages/Index.tsx\nError: Unable to apply search-replace to file"
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "<dyad-read path=\"src/pages/Index.tsx\"></dyad-read>\n\n<dyad-search-replace path=\"src/pages/Index.tsx\">\n<<<<<<< SEARCH\n // STILL Intentionally DO NOT MATCH ANYTHING TO TRIGGER FALLBACK\n <h1 className=\"text-4xl font-bold mb-4\">Welcome to Your Blank App</h1>\n=======\n <h1 className=\"text-4xl font-bold mb-4\">Welcome to the UPDATED App</h1>\n>>>>>>> REPLACE\n</dyad-search-replace>\n\n\n[[dyad-dump-path=*]]"
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "There was an issue with the following `dyad-search-replace` tags. Please fix the errors by generating the code changes using `dyad-write` tags instead.\n \nFile path: src/pages/Index.tsx\nError: Unable to apply search-replace to file"
|
||||
}
|
||||
],
|
||||
"stream": true,
|
||||
@@ -422,7 +430,8 @@
|
||||
],
|
||||
"enable_lazy_edits": false,
|
||||
"enable_smart_files_context": true,
|
||||
"smart_context_mode": "balanced"
|
||||
"smart_context_mode": "balanced",
|
||||
"app_id": 1
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
|
||||
Reference in New Issue
Block a user