Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
062013a
docs(query-insights): plan for Query Insights Next POC
tnaum-ms Oct 20, 2026
19752c0
feat(query-insights): finish model selection host plumbing (WI-0)
tnaum-ms Oct 20, 2026
218dadc
feat(query-insights): reload custom prompts on each run (WI-1)
tnaum-ms Oct 20, 2026
fca4c4c
feat(query-insights): expose shared model picker RPCs (WI-2)
tnaum-ms Oct 20, 2026
f9b3206
feat(query-insights): add shared Copilot model picker (WI-3)
tnaum-ms Oct 20, 2026
b2991a7
feat(query-insights): integrate model picker and pass checkpoint A (W…
tnaum-ms Oct 20, 2026
b5ad3ec
docs(query-insights): fix plan time log
tnaum-ms Oct 20, 2026
a52e225
refactor(query-insights): share the insights layout through a data so…
tnaum-ms Oct 20, 2026
89fe095
feat(query-insights): add connectionless analysis host (WI-6)
tnaum-ms Oct 20, 2026
a1543ff
feat(query-insights): add explorer wizard and entry points (WI-7)
tnaum-ms Oct 20, 2026
66844e1
docs(query-insights): document explorer usage and Phase B results (WI-8)
tnaum-ms Oct 20, 2026
46dbf87
feat(query-insights): add command-aware static analysis profiles (WI-9)
tnaum-ms Oct 20, 2026
8053a10
feat(query-insights): show analysis applicability and preview badges …
tnaum-ms Oct 20, 2026
e84b4e8
fix(query-insights): correct standalone analysis scope and explain da…
tnaum-ms Oct 20, 2026
6f54e38
docs(query-insights): lead review notes and time log for Phases B and C
tnaum-ms Oct 20, 2026
fbdd553
fix(query-insights): treat blank prompt paths as built-in (WI-12)
tnaum-ms Oct 20, 2026
4a88d4a
feat(query-insights): polish the explorer wizard UI (WI-13)
tnaum-ms Oct 20, 2026
7df69c0
fix(query-insights): shorten not-applicable cell values
tnaum-ms Oct 20, 2026
74b5866
fix(query-insights): keep Required tag and use rounded tint badges in…
tnaum-ms Oct 20, 2026
e8084cc
feat(query-insights): report per-run tokens and credits (WI-14)
tnaum-ms Oct 20, 2026
58f0261
feat(query-insights): enrich model picker metadata (WI-15)
tnaum-ms Oct 20, 2026
71a00ff
feat(query-insights): slim Analyze header (WI-16)
tnaum-ms Oct 20, 2026
3c11462
feat(query-insights): mirror Chat pricing details (WI-15 follow-up)
tnaum-ms Oct 20, 2026
30c8ada
feat(query-insights): add Monaco inputs and verify Phase E (WI-17)
tnaum-ms Oct 20, 2026
5992cc2
style(query-insights): align model pricing panel with house style
tnaum-ms Oct 20, 2026
5374be9
feat(query-insights): model table layout, Powerful default, results t…
tnaum-ms Oct 20, 2026
702de9c
style(query-insights): numbered 'What you'll need' list with title ba…
tnaum-ms Oct 20, 2026
f0c89c3
feat(query-insights): dev-only design preview of tab model-selection …
tnaum-ms Oct 20, 2026
516356c
docs(query-insights): log Phase F review
tnaum-ms Oct 20, 2026
d9b2315
feat(query-insights): ship design Option A in the tab card; drop 'Fre…
tnaum-ms Oct 20, 2026
11be452
feat(query-insights): standard Fluent model dropdown with details pop…
tnaum-ms Oct 21, 2026
41765ac
fix(query-insights): visible small 'Copilot model' label in the wizar…
tnaum-ms Oct 21, 2026
a717909
feat(query-insights): compare Fluent model controls in live analysis …
tnaum-ms Oct 21, 2026
0d7f0f7
feat(query-insights): select underline model picker and clarify model…
tnaum-ms Oct 21, 2026
4c19f65
fix(query-insights): move model controls into cost disclosure footer
tnaum-ms Oct 21, 2026
6b6a1f0
feat(query-insights): model picker before the action, prompt source t…
tnaum-ms Oct 22, 2026
c649a95
chore: refresh localization and format query insights changes
tnaum-ms Oct 22, 2026
11d951a
fix: resolve query insights lint errors
tnaum-ms Oct 22, 2026
a92d3a1
style: organize model picker test imports
tnaum-ms Oct 22, 2026
afa2257
feat(query-insights): prefer a packaged local prompt when present
tnaum-ms Oct 23, 2026
8608ae0
fix(query-insights): survive non-array stage children and keep the ra…
tnaum-ms Oct 23, 2026
43a9483
feat(query-insights): dedicated card for non-index recommendations
tnaum-ms Oct 23, 2026
f3720e7
fix(query-insights): handle DocumentDB indexUsage reported as an object
tnaum-ms Oct 23, 2026
21aaafb
feat(query-insights): copy feedback on recommendation cards
tnaum-ms Oct 23, 2026
b87e14c
feat(query-insights): copy the optimization opportunities as Markdown
tnaum-ms Oct 23, 2026
d5c5aa3
fix(query-insights): report DocumentDB primary-key order scans as col…
tnaum-ms Oct 23, 2026
9c3161d
feat(query-insights): Share menu with Markdown and rich-text copy
tnaum-ms Oct 23, 2026
c3cabe5
refactor(query-insights): make the Markdown report the single source …
tnaum-ms Oct 23, 2026
72f0bca
fix(query-insights): resolve lint errors
tnaum-ms Oct 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
## files generated by popular Visual Studio add-ons.

._local/
# Local Query Insights prompt override: packaged when present, never committed.
resources/prompts/local/

# User-specific files
*.suo
Expand Down
130 changes: 130 additions & 0 deletions build/verification/browser/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { type ClusterDashboardWebviewConfigurationType } from '../../../src/webv
import { type CollectionViewWebviewConfigurationType } from '../../../src/webviews/documentdb/collectionView/collectionViewController';
import { type DocumentsViewWebviewConfigurationType } from '../../../src/webviews/documentdb/documentView/documentsViewController';
import { type LocalQuickStartConfigurationType } from '../../../src/webviews/documentdb/localQuickStart/localQuickStartController';
import { type QueryInsightsPrefill } from '../../../src/webviews/documentdb/queryInsightsStandalone/types';
import { type FixtureInputs, type FixtureOutputs, type RpcFixture, type RpcFixtures } from './core/fixtures';

type Inputs = FixtureInputs;
Expand Down Expand Up @@ -82,6 +83,10 @@ const quickStartConfig: LocalQuickStartConfigurationType = {
initialInstanceState: InstanceState.NotInstalled,
};
const atlasConfig: AtlasCredentialsWebviewConfig = { mode: 'add', authMethod: 'apikey' };
/** A fresh open opens on Welcome; scenarios add {@link queryInsightsSampleExplain} to start on Configure. */
const queryInsightsConfig: QueryInsightsPrefill = { databaseName: 'demo', collectionName: 'items' };
export const queryInsightsSampleExplain =
'{"queryPlanner":{"winningPlan":{"stage":"COLLSCAN"}},"executionStats":{"nReturned":2,"executionTimeMillis":12,"totalDocsExamined":100,"totalKeysExamined":0}}';
interface FixtureTableRow {
readonly id: string;
readonly 'x-objectid': string;
Expand Down Expand Up @@ -245,6 +250,131 @@ export const fixtures = {
'localQuickStart.onInstanceChanged': { type: 'subscription', results: [instance], keepOpen: true },
},
},
queryInsightsStandalone: {
config: queryInsightsConfig,
monaco: false,
content: [
'Query Insights Explorer',
"What you'll need",
'Get the explain output',
'What is sent to GitHub Copilot',
],
styles: [{ selector: 'body', property: 'padding-top', expected: '0px' }],
rpc: {
...common,
'ai.getAvailableModels': reply<Outputs['ai']['getAvailableModels']>('query', {
models: [
{
id: 'copilot-utility',
name: 'Copilot utility',
family: 'copilot-utility',
vendor: 'copilot',
version: '1',
maxInputTokens: 64000,
isUtility: true,
pricing: 'Free',
priceCategory: 'low',
category: 'lightweight',
inputCost: 0,
outputCost: 0,
cacheCost: 0,
supportsToolCalling: true,
supportsImageToText: false,
},
],
savedModelId: null,
effectiveModelId: 'copilot-utility',
effectiveReason: 'first-available',
}),
'queryInsightsStandalone.validateInput': reply<Outputs['queryInsightsStandalone']['validateInput']>(
'query',
{
commandType: 'find' as Outputs['queryInsightsStandalone']['validateInput']['commandType'],
query: '{}',
},
),
'queryInsightsStandalone.inspectInput': reply<Outputs['queryInsightsStandalone']['inspectInput']>('query', {
explain: {
ok: true,
detectedCommandType: 'find' as Outputs['queryInsightsStandalone']['validateInput']['commandType'],
planStages: ['COLLSCAN'],
},
commandType: 'find' as Outputs['queryInsightsStandalone']['validateInput']['commandType'],
query: '{}',
queryIsExtracted: true,
ready: true,
}),
'queryInsightsStandalone.getStage1': reply<Outputs['queryInsightsStandalone']['getStage1']>('query', {
executionTime: 0,
stages: [{ stage: 'COLLSCAN', name: 'Collection scan', nReturned: 0 }],
efficiencyAnalysis: { executionStrategy: 'Collection scan', indexUsed: null, hasInMemorySort: false },
}),
'queryInsightsStandalone.getStage2': reply<Outputs['queryInsightsStandalone']['getStage2']>('query', {
executionTimeMs: 12,
documentsReturned: 2,
totalDocsExamined: 100,
totalKeysExamined: 0,
examinedToReturnedRatio: 50,
keysToDocsRatio: 0,
executionStrategy: 'Collection scan',
indexUsed: false,
usedIndexNames: [],
hadInMemorySort: false,
hadCollectionScan: true,
isCoveringQuery: false,
concerns: [],
rawExecutionStats: {},
stages: [{ stage: 'COLLSCAN', name: 'Collection scan', nReturned: 2 }],
efficiencyAnalysis: {
selectivity: null,
indexUsed: null,
fetchOverhead: 'Collection scan',
fetchOverheadKind: 'collectionScan',
hasInMemorySort: false,
performanceRating: { score: 'poor', diagnostics: [] },
},
}),
'queryInsightsStandalone.streamStage3': {
type: 'subscription',
results: [
{ type: 'summary', markdown: 'Consider indexing the filter.', complete: true },
{ type: 'recommendationStarted', index: 0 },
{
type: 'recommendation',
index: 0,
recommendation: {
action: 'create',
indexSpec: { status: 1 },
indexName: 'status_1',
shellCommand: 'db.items.createIndex({status: 1})',
justification: 'Avoid a collection scan.',
priority: 'high',
},
},
{
type: 'complete',
modelId: 'copilot-utility',
modelFamily: 'copilot-utility',
modelDisplayName: 'Copilot utility',
durationMs: 10,
usage: {
promptTokens: 1200,
responseTokens: 350,
credits: 0,
reportedPromptTokens: 1200,
reportedCompletionTokens: 350,
usageSource: 'provider',
},
},
] as const,
},
'common.copyToClipboard': reply<Outputs['common']['copyToClipboard']>('mutation', true),
'queryInsightsStandalone.openRawExplain': reply<Outputs['queryInsightsStandalone']['openRawExplain']>(
'mutation',
true,
),
},
},
atlasCredentials: {
config: atlasConfig,
monaco: false,
Expand Down
3 changes: 2 additions & 1 deletion build/verification/browser/harness.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,14 @@ describe('Stage 0 L2 production browser harness', (): void => {
}
});

it('covers all five registry keys with populated fixture contracts', (): void => {
it('covers all six registry keys with populated fixture contracts', (): void => {
expect(Object.keys(fixtures).sort()).toEqual([
'atlasCredentials',
'clusterDashboard',
'collectionView',
'documentView',
'localQuickStart',
'queryInsightsStandalone',
]);
for (const fixture of Object.values(fixtures)) {
expect(fixture.content.length).toBeGreaterThan(0);
Expand Down
1 change: 1 addition & 0 deletions build/verification/browser/runtime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ function isHarnessFixture(value: unknown): value is HarnessFixture {
documentView: true,
localQuickStart: true,
atlasCredentials: true,
queryInsightsStandalone: true,
} satisfies Record<WebviewName, boolean>;
return (
isObject(value) &&
Expand Down
9 changes: 5 additions & 4 deletions build/verification/browser/scenarios.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { parseScenarioRoute, runnerRoutes, scenarioHtml, scenarioIndex, scenario
import { findScenario, scenarioRoutes, scenarios, type Scenario } from './scenarios';

describe('L2-dev manifest and routes', (): void => {
it('imports, rather than duplicates, all five settled L2 fixtures', (): void => {
it('imports, rather than duplicates, all six settled L2 fixtures', (): void => {
for (const route of scenarioRoutes().filter((route): boolean => route.scenario === 'default')) {
const scenario = findScenario(route);
expect(scenario.config).toBe(fixtures[route.view].config);
Expand All @@ -23,8 +23,8 @@ describe('L2-dev manifest and routes', (): void => {

it('round-trips every scenario and theme, without duplicate routes', (): void => {
const routes = scenarioRoutes();
expect(routes).toHaveLength(42);
expect(new Set(routes.map((route): string => route.path)).size).toBe(42);
expect(routes).toHaveLength(72);
expect(new Set(routes.map((route): string => route.path)).size).toBe(72);
for (const route of routes) expect(parseScenarioRoute(route.path)).toEqual(route);
});

Expand All @@ -50,7 +50,8 @@ describe('L2-dev manifest and routes', (): void => {
});

it('provides path-only all/view/theme helpers and rejects unknown subsets', (): void => {
expect(runnerRoutes('/scenarios/run-all.js')).toHaveLength(42);
expect(runnerRoutes('/scenarios/run-all.js')).toHaveLength(72);
expect(runnerRoutes('/scenarios/run-all/queryInsightsStandalone.js')).toHaveLength(30);
expect(runnerRoutes('/scenarios/run-all/localQuickStart.js')).toHaveLength(30);
expect(runnerRoutes('/scenarios/run-all/localQuickStart/dark.js')).toHaveLength(10);
expect(runnerRoutes('/scenarios/run-all/unknown.js')).toBeUndefined();
Expand Down
Loading
Loading