smart context v3 (#1022)

<!-- This is an auto-generated description by cubic. -->

## Summary by cubic
Adds Smart Context v3 with selectable modes (Off, Conservative,
Balanced) and surfaces token savings in chat. Also improves token
estimation by counting per-file tokens when Smart Context is enabled.

- **New Features**
- Smart Context selector in Pro settings with three options.
Conservative is the default when enabled without an explicit choice.
- New setting: proSmartContextOption ("balanced"); undefined implies
Conservative.
- Engine now receives enable_smart_files_context and smart_context_mode.
- Chat shows a DyadTokenSavings card when the message contains
token-savings?original-tokens=...&smart-context-tokens=..., with percent
saved and a tooltip for exact tokens.
- Token estimation uses extracted file contents for accuracy when Pro +
Smart Context is on; otherwise falls back to formatted codebase output.

<!-- End of auto-generated description by cubic. -->
This commit is contained in:
Will Chen
2025-08-20 14:16:07 -07:00
committed by GitHub
parent 34215db141
commit 4e9a927a7b
18 changed files with 764 additions and 26 deletions

View File

@@ -86,13 +86,23 @@ export function registerTokenCountHandlers() {
if (chat.app) {
const appPath = getDyadAppPath(chat.app.path);
codebaseInfo = (
await extractCodebase({
appPath,
chatContext: validateChatContext(chat.app.chatContext),
})
).formattedOutput;
codebaseTokens = estimateTokens(codebaseInfo);
const { formattedOutput, files } = await extractCodebase({
appPath,
chatContext: validateChatContext(chat.app.chatContext),
});
codebaseInfo = formattedOutput;
if (settings.enableDyadPro && settings.enableProSmartFilesContextMode) {
codebaseTokens = estimateTokens(
files
// It doesn't need to be the exact format but it's just to get a token estimate
.map(
(file) => `<dyad-file=${file.path}>${file.content}</dyad-file>`,
)
.join("\n\n"),
);
} else {
codebaseTokens = estimateTokens(codebaseInfo);
}
logger.log(
`Extracted codebase information from ${appPath}, tokens: ${codebaseTokens}`,
);