feat(lens): geographic filter on Discover lenses (locations)#116
Open
ArtyETH06 wants to merge 4 commits into
Open
feat(lens): geographic filter on Discover lenses (locations)#116ArtyETH06 wants to merge 4 commits into
ArtyETH06 wants to merge 4 commits into
Conversation
new_lens and adjust_audience now accept `locations` / `exclude_locations` (free text auto-resolved via /geo/search, or admin-area ids), writing a `location_ids` lens-filter criterion. Mirrors the existing sector path: resolve first, bail with `ambiguous_locations` before mutating, merge into the filter via mergeFilter. The backend already supported a `location_ids` lens criterion (verified live: POST /lenses/:id/filter → 204, populates the locations echo block); only the MCP never exposed it. Unblocks programmatic sales-territory scoping on the discovery surface — the "scope a territory → net-new accounts there" cockpit workflow (product#3759). Co-Authored-By: Claude <noreply@anthropic.com>
When an exclude_locations entry resolved ambiguously, the recovery message told the agent to re-call with location_ids — the include-only param — which silently flipped "exclude Springfield" into "include Springfield". Split the include vs exclude ambiguity messages so each steers to its correct retry param (exclude_locations for excluded picks), in both new_lens and adjust_audience. Regression test added. Addresses PR #116 review (P2). Co-Authored-By: Claude <noreply@anthropic.com>
The execute-path message was already exclude-safe, but the outputSchema descriptions for ambiguous_locations still told clients to always re-call with location_ids — so a schema-driven agent could re-submit an ambiguous EXCLUDE pick via the include param and add an area the user asked to exclude. Make the schema guidance route by axis (include → location_ids/locations; exclude → exclude_locations) in both adjust_audience and new_lens. Addresses PR #116 review (P2, follow-up). Co-Authored-By: Claude <noreply@anthropic.com>
The runtime message and output schemas were already exclude-safe, but the tool-description templates still told the model to re-call ambiguous locations with location_ids unconditionally — so a model following the description could turn "exclude Springfield" into "include Springfield". Route the retry by axis (include → location_ids/locations; exclude → exclude_locations) in both adjust-audience and new-lens templates; regenerated descriptions. Addresses PR #116 review (P2, third surface). Co-Authored-By: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
leadbay_new_lensandleadbay_adjust_audiencenow acceptlocations/exclude_locations— a geographic dimension on the Discover lens, mirroring the existing sector path:["Indre-et-Loire"],["Texas"]) auto-resolves via/geo/search(reusingresolveLocationsfrom_geo-helpers.ts), or pass admin-area ids directly;ambiguous_locationsand the lens is not mutated (no half-built lens);location_idscriterion viamergeFilter.Why
The MCP could already geo-filter the Monitor side (
pull_followups+location_ids) but had no way to set geography on a Discover lens —adjust_audience/new_lenstook only sector/size. A sales director couldn't scope a rep's territory (a département) and ask for net-new accounts there without leaving the agent for the web UI. This unblocks the "scope a territory → net-new accounts there" cockpit workflow.The backend already supported a
location_idslens criterion — only the MCP never exposed it. This is a pure MCP-layer fix.Changes
mergeFilterextended with optionaltoAddLocations/toExcludeLocations(additive — existing callers unchanged).new_lens+adjust_audience: new params, schema,ambiguous_locationsbail, preview surfacing.WORKFLOWS.mdrow 35 (territory scoping) + contract.new-lens-geo.test.ts,adjust-audience-geo.test.ts(9 cases — happy path, ambiguity bail, id-passthrough, exclude, sector coexistence).Verification
pnpm -r build/pnpm -r test/pnpm -r typecheck— all green (948 tests; 9 new).new_lens(locations:["Texas"])→ created with{type:"location_ids",is_excluded:false,locations:["6029"]}; read-back populated thelocationsecho block[{id:"6029",name:"Texas"}];adjust_audience(exclude_locations:["California"])added anis_excluded:truecriterion alongside; test lens deleted./eval— Workflow 35 (prod):MM 5 / IA 5 / NF 5 / TSF 5, invariants 3/3 PASS. Prompt "Create a lens for net-new accounts in Texas" routed toleadbay_new_lenswithlocations:["Texas"], hit the confirm gate, never misrouted geography to a sector/refine_prompt;leadbay_report_outreachabsent. Not covered: theask_user_input_v0widget didn't render in the minimal eval harness (fell back to prose) — a harness artifact, not a product issue.Closes https://github.com/leadbay/product/issues/3759