Apply upstream commit 1572d90d7174f0c65019e768c8f65728fae668c5 from PR #1570 by @rongbc. Clarify that suggested explore call counts are advisory and extra calls remain available. Sync the MCP initialization guidance and eval probe, retain the upstream regression tests, close the footer's bold formatting, and credit the fix under Unreleased in the changelog. Validation: npm run build; focused Vitest (3 files, 53 tests); source and dist wording greps; git diff --check. Fixes #1504 Co-authored-by: Colby McHenry <colbymchenry@users.noreply.github.com>
This commit is contained in:
co-authored by
Colby McHenry
parent
1f4379d95f
commit
e79d5df448
@@ -6,7 +6,7 @@
|
||||
* grep+Read. These tests pin the per-tier budget shape so future tuning
|
||||
* doesn't silently drift the small-project case back into bloat.
|
||||
*/
|
||||
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
||||
import { describe, it, expect, vi, beforeAll, afterAll } from 'vitest';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
@@ -198,7 +198,26 @@ describe('codegraph_explore output respects the adaptive budget', () => {
|
||||
const text = result.content?.[0]?.text ?? '';
|
||||
expect(text).not.toContain('### Additional relevant files');
|
||||
expect(text).not.toContain('Complete source code is included above');
|
||||
expect(text).not.toContain('Explore budget:');
|
||||
expect(text).not.toContain('advisory only, NOT a quota');
|
||||
});
|
||||
|
||||
it('emits advisory-only exploration guidance on medium projects — never quota wording', async () => {
|
||||
// Medium tier (500–4,999 files) turns the guidance note on. The synthetic
|
||||
// project is tiny, so fake the stats to land in that tier — the note's
|
||||
// WORDING is what this test pins. Regression guard: quota phrasing
|
||||
// ("remaining calls" / "Synthesize once") must never come back — agents
|
||||
// read it as a hard cap, stop exploring early, and fall back to grep+Read.
|
||||
const spy = vi.spyOn(cg, 'getStats').mockReturnValue({ fileCount: 1000 } as ReturnType<CodeGraph['getStats']>);
|
||||
try {
|
||||
const result = await handler.execute('codegraph_explore', { query: 'Session method helper' });
|
||||
const text = result.content?.[0]?.text ?? '';
|
||||
expect(text).toContain('advisory only, NOT a quota');
|
||||
expect(text).toContain('extra calls are never rejected or rate-limited');
|
||||
expect(text).not.toContain('remaining calls');
|
||||
expect(text).not.toContain('Synthesize once');
|
||||
} finally {
|
||||
spy.mockRestore();
|
||||
}
|
||||
});
|
||||
|
||||
it('still includes the Relationships section — it is the cheapest structural signal', async () => {
|
||||
|
||||
@@ -108,11 +108,12 @@ describe('Live tool surface keeps annotations with a project open (#1018)', () =
|
||||
expect(got.length).toBeGreaterThan(0);
|
||||
for (const tool of got) expectReadOnly(tool);
|
||||
|
||||
// explore's description is regenerated with a per-repo budget suffix via
|
||||
// object spread; the annotation must survive that rewrite.
|
||||
// explore's description is regenerated with a per-repo advisory-guidance
|
||||
// suffix via object spread; the annotation must survive that rewrite.
|
||||
const explore = got.find((t) => t.name === 'codegraph_explore');
|
||||
expect(explore).toBeDefined();
|
||||
expect(explore!.description).toMatch(/Budget: make at most/);
|
||||
expect(explore!.description).toMatch(/advisory only, NOT a quota/);
|
||||
expect(explore!.description).not.toMatch(/make at most/);
|
||||
expectReadOnly(explore!);
|
||||
expectExploreAlwaysLoad(got);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user