Skip to content

feat(search): answer intents and repositories in the search box - #440

Merged
harlan-zw merged 3 commits into
mainfrom
feat/search-intent
Oct 5, 2026
Merged

harlan-zw merged 3 commits into
mainfrom
feat/search-intent

Conversation

@harlan-zw

Copy link
Copy Markdown
Collaborator

🔗 Linked issue

None.

❓ Type of change

  • 📖 Documentation
  • 🐞 Bug fix
  • 👌 Enhancement
  • ✨ New feature
  • 🧹 Chore
  • ⚠️ Breaking change

📚 Description

The search box says "Search skills or repos", but it handled neither repos nor intent well. vercel-labs/agent-skills came back as "Loose matches: No skill contains those words", although the registry holds that Repository. A pasted GitHub URL only offered to index the repo again. A sentence such as "write a postgres migration" was searched as separate words.

The box now calls a new internal GET /api/skills/search, which classifies the query before it searches:

  • A GitHub URL or owner/repo answers with a Repository row and its Skills. A Repository the registry does not hold gets the existing index flow.
  • @login lists that owner's Skills. A single word runs the existing hybrid search unchanged.
  • A sentence goes through @cf/meta/llama-3.1-8b-instruct-fast once. The model returns search terms plus a track, a framework and an author. The hybrid search then runs on the typed words and the terms. Track and framework only lift near ties. They never filter.

Guardrails on the model call:

  • The answer is cached per normalised query for 30 days in edge-cache. A reply the model cannot parse is cached as "none" for a day.
  • The budget is 800ms. After that, or on any model error, search runs on the typed words. A late reply still lands in the cache.
  • Names, refs, URLs and logins skip the model. Each visitor's model calls go through the existing API_GUEST_RATE_LIMIT binding under a search-intent: key. Over the limit, search runs on the typed words.
  • Wide events record the fallback reason only, never the query.
  • The model is a native Workers AI model billed in neurons, so it needs no AI Gateway credits. A call is about 525 input and 30 output tokens, about $0.036 per 1,000 calls.

The public skills.search v1 answer and the MCP tools are unchanged.

In the panel, each Skill row shows its RunChip compact, and a Repository gets its own row with its Skill count. A name also shows matching Repositories from the typeahead index the browser already holds. The panel is now a grid, because an ARIA option cannot contain a button: Right moves to the run chip and Enter copies it. HomeSearch (the hero from #437) and SkillSearchTrigger share useSkillSearchBox, so Enter means the same in both: open a row selected with the keyboard, otherwise submit. The header field widens while open, the half-empty preview pane is gone, and owner paths truncate instead of crushing Skill names at phone width.

"See all results" for a sentence opens /skills with its meaning search on. That mode was labelled "Ask AI" and "AI search", which COPY.md bans, so it now reads "Search by meaning" and "Results by meaning".

Architecture: both search boxes call the new /api/skills/search, which classifies the query, runs query understanding for sentences through Workers AI, and reuses querySkills; v1 search and the MCP tools stay unchanged

Stage 2, not built

An agent loop could answer what a one-shot rewrite cannot. "stop memory leaks in node" still returns Godot and Tokio Skills, because the embeddings rank them first.

  • Loop: Claude Haiku 4.5 through AI Gateway, with the existing mcpTools from layers/mcp/shared/mcp-tools.ts as its tools (search_skills, get_skill, get_collection). Cap it at 4 turns and let it return Skill refs only.
  • Cost: about 21k input and 1.2k output tokens per question. At $1 and $5 per million tokens that is about $0.027, or about $0.015 with prompt caching on the system prompt and tools. That is roughly 750 times a stage 1 call.
  • Credits: the AI Gateway balance is empty (see send-digests.ts). A $10 top-up covers about 400 to 650 questions.
  • Caching: AI Gateway response caching for identical requests, plus an answer cache by normalised question, as stage 1 does.
  • UI: opt in only, never per keystroke. A "Find Skills for this task" row at the foot of the panel for sentences, a short streamed answer with Skill rows and run chips, and a daily cap per visitor.

🤖 AI disclosure: Harlan Agent Kit modified this description. My AI open-source policy.

The search box promises skills or repos, but a repo ref fell through to a
semantic search and called its own Skills loose matches, and a sentence was
searched word by word. A new internal /api/skills/search classifies the query
first: a URL or owner/repo answers with that Repository and its Skills, @login
with that owner, and a sentence passes through a small Workers AI model that
turns it into search terms and soft boosts before the existing hybrid search.

The model is cached per normalised query for a month, abandoned after 800ms,
skipped for names, refs and URLs, and gated by the guest rate limiter. The
frozen v1 skills.search answer is unchanged.
Each Skill row now carries its run chip, and a Repository the registry holds
gets its own row, so the box answers both halves of its placeholder. The
panel becomes a grid because an option cannot contain a control: arrow
right moves to the run chip and Enter copies it.

The hero and header boxes share one composable for keys, selection and
navigation, so they stop disagreeing about what Enter does. The header
field widens while open, rows keep their names readable at phone width,
and the preview pane with its empty half is gone.
COPY.md bans AI as a modifier on skilld. The search box now sends sentences
to this mode, so its label says what the mode does.
@harlan-github-agent harlan-github-agent Bot added harlan-agent-running An Agent holds a Task on this issue or pull request right now. harlan-agent-review-required Pull request triage requires an adversarial Review for this head commit. labels Oct 5, 2026
@harlan-github-agent

harlan-github-agent Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

🤖 MERGED

Harlan Agent Kit posted this automated review. It is not Harlan's personal review or approval. AI open source policy. Last updated: 2026-10-05 17:31 UTC.

GitHub merged this pull request.

  • Logged (42/100): Enter on a word-pair owner/repo query the registry lacks starts a doomed index flow instead of the search it used to run, and hides the loose-match disclosure. View code
    • Ask an agent to verify and fix this finding
  • Logged (27/100): A container-query breakpoint keyed to the viewport's md width always matches the capped-width panel, so the sources badge and the run-command key hint never render. View code
    • Ask an agent to verify and fix this finding
  • Logged (25/100): A rate limiter error propagates and 500s the search box instead of falling back to the typed words. View code
    • Ask an agent to verify and fix this finding
  • Logged (15/100): The pull request's architecture diagram is inaccessible at head, a material documentation gap for the only visual in the description.
    • Ask an agent to verify and fix this finding

Review completed. No finding above 80/100.

Selected findings run after merge and open separate pull requests.

@harlan-zw

Copy link
Copy Markdown
Collaborator Author

Agent check, run by hand because CI cannot cover it. A local build of this branch served the 20 queries below against production D1, Vectorize and Workers AI, read only. Before is production today. After shows the top three Skills once the understanding is cached.

Query Before (production) After (this branch)
vercel-labs/agent-skills "Loose matches": vercel-agent, benchmark-agents, vercel-sandbox Repository row (9 Skills), then composition-patterns, deploy-to-vercel, react-best-practices
https://github.com/vercel-labs/agent-skills Index row only Same Repository row and Skills
github.com/anthropics/skills creating-skills, skill-developer, anthropic-architect Repository row (20 Skills), then its Skills
@antfu Hybrid search, 58 hits antfu's 11 Skills
write better commit messages git-commit-formatter, commit-helper, git-commit-format writing-commit-messages (agenteq), writing-commit-messages (herdr), commit-messages
make my UI less generic make-interfaces-feel-better, ui-design, soft-skill frontend-design (anthropics), ui-design-system, ui-design
reacct hooks creating-hooks, git-guardrails-claude-code, viral-hook-creator react-hooks-best-practices, creating-hooks, trigger-realtime
playwrite e2e tests write-e2e-tests, e2e-testing, playwriter playwright-e2e-testing, e2e-testing, api-testing
write a postgres migration postgres-drizzle, neon-postgres-branches, postgres postgres-database-migration, postgres-drizzle, postgres
set up stripe payments stripe/ai Skills stripe/ai Skills, filtered to the stripe owner
review my pull requests gh-review-requests, skill, pr-review creating-pull-request, addressing-code-review-comments, pr-review (mixed)
deploy to cloudflare workers cloudflare-deploy, workers-best-practices, cloudflare cloudflare-deploy, nextjs-on-cloudflare, cloudflare-vpc-services (mixed)
stop memory leaks in node godot-debugging-profiling, tokio-troubleshooting, ios-memgraph-analysis Unchanged miss
test a Vue app, vitest, nuxt, antfu, mattpocock, tailwnd, anthropics/skills/frontend-design Already right Same Skills; names also show matching Repository rows

Also checked:

  • On a cold local request, 3 of 10 sentences passed the 800ms budget through the local remote-binding proxy and fell back to the typed words. The late replies reached the cache, and the next refresh served the understood results.
  • axe-core on the open panel, with the run chip cell active, reported no violations. Enter on that cell copied the command and did not navigate.
Before After
Before: a repository ref returns loose matches After: the Repository row leads, each Skill has its run chip
Before: Skill names truncate at phone width After: a sentence at phone width, with run chips
Before: header panel with an empty preview pane After: header panel, run chip selected with the keyboard

@harlan-zw
harlan-zw merged commit 2549f56 into main Oct 5, 2026
7 checks passed
@harlan-github-agent harlan-github-agent Bot removed harlan-agent-running An Agent holds a Task on this issue or pull request right now. harlan-agent-review-required Pull request triage requires an adversarial Review for this head commit. labels Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant