Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions eval/agentic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ use at least one agent for quick iteration.
| Agent-driven GitHits onboarding and setup UX | `githits-onboarding.md` |
| Core global examples, `get_example`, `search_language`, `feedback` | `global-example.md` |
| Unified `search` / `search_status` behavior | `unified-search-investigation.md`; use `search-source-ergonomics.md` when changing `search` source-selection arguments or minimal-call guidance |
| Explicit standalone site targets in unified `search` | `site-search-explicit.md` |
| Package overview or vulnerability UX, `pkg_info`, `pkg_vulns` | `package-overview-vulnerabilities.md`; use `package-vulnerability-filter.md` for severity/version filtering behavior; use `package-vulnerability-history.md` for historical/non-affecting advisory scope behavior |
| Dependency graph UX, `pkg_deps` | `package-dependencies.md` |
| Release notes UX, `pkg_changelog` | `package-changelog.md`; use `package-changelog-range.md` for range/body-preview behavior |
Expand Down
6 changes: 6 additions & 0 deletions eval/agentic/workloads/site-search-explicit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Workload: Explicit Site Search

Find documentation on `site:expressjs.com` about Express routers. Summarize the
relevant routing behavior and include source URLs or page IDs inside the
`answer` field. Do not add extra top-level JSON fields beyond the reporting
schema.
210 changes: 210 additions & 0 deletions packages/core-internal/src/services/code-navigation-service.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,216 @@ describe("CodeNavigationServiceImpl", () => {
stderrSpy.mockRestore();
});

it("requests documentation coverage and site fields in the search query", async () => {
const fn = mockFetch(() =>
Promise.resolve(
new Response(
JSON.stringify({
data: {
search: {
completed: true,
searchRef: null,
result: {
query: "router",
queryWarnings: [],
sources: ["DOCS"],
results: [],
page: { offset: 0, limit: 20, returned: 0, hasMore: false },
partialResults: false,
sourceStatus: [],
},
progress: null,
},
},
}),
{ headers: { "Content-Type": "application/json" } },
),
),
);
const service = new CodeNavigationServiceImpl(
BASE_URL,
createMockTokenProvider(),
globalThis.fetch,
);

await service.search({
targets: [{ site: "site:expressjs.com" }],
query: "router",
});

const [, init] = fn.mock.calls[0] as unknown as [string, RequestInit];
const query = JSON.parse(init.body as string).query as string;
expect(query).toContain("coverageState");
expect(query).toContain("frontierRemaining");
// requestedTargets must select `site`, otherwise standalone site
// targets echo back as empty objects during progress polling.
expect(query).toMatch(/requestedTargets\s*{[^}]*site/);
});

it("normalises documentation coverage on source status", async () => {
mockFetch(() =>
Promise.resolve(
new Response(
JSON.stringify({
data: {
search: {
completed: true,
searchRef: null,
result: {
query: "router",
queryWarnings: [],
sources: ["DOCS"],
results: [],
page: { offset: 0, limit: 20, returned: 0, hasMore: false },
partialResults: false,
sourceStatus: [
{
source: "DOCS",
targetLabel: "site:expressjs.com",
appliedFilters: [],
ignoredFilters: [],
incompatibleFilters: [],
appliedQueryFeatures: [],
ignoredQueryFeatures: [],
incompatibleQueryFeatures: [],
coverage: {
coverageState: "PARTIAL",
pagesCrawled: 42,
frontierRemaining: 158,
note: "Site crawl is in progress",
},
},
],
},
progress: null,
},
},
}),
{ headers: { "Content-Type": "application/json" } },
),
),
);
const service = new CodeNavigationServiceImpl(
BASE_URL,
createMockTokenProvider(),
globalThis.fetch,
);

const outcome = await service.search({
targets: [{ site: "site:expressjs.com" }],
query: "router",
});

if (outcome.state !== "completed") throw new Error("expected completed");
expect(outcome.result.sourceStatus[0]?.coverage).toEqual({
coverageState: "PARTIAL",
pagesCrawled: 42,
frontierRemaining: 158,
note: "Site crawl is in progress",
});
});

it("drops NONE documentation coverage as carrying no signal", async () => {
mockFetch(() =>
Promise.resolve(
new Response(
JSON.stringify({
data: {
search: {
completed: true,
searchRef: null,
result: {
query: "router",
queryWarnings: [],
sources: ["DOCS"],
results: [],
page: { offset: 0, limit: 20, returned: 0, hasMore: false },
partialResults: false,
sourceStatus: [
{
source: "DOCS",
targetLabel: "site:expressjs.com",
appliedFilters: [],
ignoredFilters: [],
incompatibleFilters: [],
appliedQueryFeatures: [],
ignoredQueryFeatures: [],
incompatibleQueryFeatures: [],
coverage: { coverageState: "NONE", pagesCrawled: 0 },
},
],
},
progress: null,
},
},
}),
{ headers: { "Content-Type": "application/json" } },
),
),
);
const service = new CodeNavigationServiceImpl(
BASE_URL,
createMockTokenProvider(),
globalThis.fetch,
);

const outcome = await service.search({
targets: [{ site: "site:expressjs.com" }],
query: "router",
});

if (outcome.state !== "completed") throw new Error("expected completed");
expect(outcome.result.sourceStatus[0]?.coverage).toBeUndefined();
});

it("serializes standalone site targets for unified search", async () => {
const fn = mockFetch(() =>
Promise.resolve(
new Response(
JSON.stringify({
data: {
search: {
completed: true,
searchRef: null,
result: {
query: "router middleware",
queryWarnings: [],
sources: ["DOCS"],
results: [],
page: {
offset: 0,
limit: 20,
returned: 0,
hasMore: false,
},
partialResults: false,
sourceStatus: [],
},
progress: null,
},
},
}),
{ headers: { "Content-Type": "application/json" } },
),
),
);
const service = new CodeNavigationServiceImpl(
BASE_URL,
createMockTokenProvider(),
globalThis.fetch,
);

await service.search({
targets: [{ site: "site:expressjs.com" }],
query: "router middleware",
sources: ["DOCS"],
});

const [, init] = fn.mock.calls[0] as unknown as [string, RequestInit];
const body = JSON.parse(init.body as string);
expect(body.variables.targets).toEqual([{ site: "site:expressjs.com" }]);
});

it("throws CodeNavigationIndexingError for data-path INDEXING sentinel on grepRepo", async () => {
mockFetch(() =>
Promise.resolve(
Expand Down
Loading