{"slug": "i-built-an-openai-compatible-proxy-for-github-copilot-because-search-was-too-to", "title": "I Built an OpenAI-Compatible Proxy for GitHub Copilot Because Search Was Too Stupid to Understand Norwegian Guitar Tabs", "summary": "A developer built an OpenAI-compatible proxy for GitHub Copilot CLI, named *agentry*, to power a semantic search engine for Norwegian guitar tabs. The project, called NorTabs-web, uses an LLM enrichment pipeline to add metadata like mood and genre to thousands of hand-transcribed tabs, enabling search by abstract concepts like \"melancholic\" or \"roadtrip\" rather than exact text matches. The proxy keeps the Copilot backend warm to reduce latency, allowing any OpenAI-compatible client to query the enriched tab database.", "body_md": "I named it *agentry* (because it gives an ai agent persistent entry)\n\nSoftware projects are supposed to begin with a sensible problem and proceed toward a proportionate solution.\n\nMine began with:\n\n“Why can’t I search for that bittersweet Trønderrock song about driving home from a funeral?”\n\nNormal people would shrug and type a few more words.\n\nI, being from Northern Norway and therefore apparently incapable of leaving a thing alone, built a semantic search engine, an LLM enrichment pipeline, and eventually an OpenAI-compatible proxy in front of GitHub Copilot CLI.\n\nThis is, objectively, a silly use of modern compute.\n\nAnd yet.\n\nI have a hobby project called **NorTabs-web**, a static web app for browsing Norwegian guitar tabs.\n\nNot Spotify. Not some venture-funded AI music startup. Just thousands of lovingly hand-transcribed guitar tabs from a Norwegian site, packed into one giant JSON blob and served in a browser like it’s 1999.\n\nLoad-time is a wee bit slow - content is about 7mb; About the same as a larg-ish image. Search/Drilldown is INSTANT however.\n\nRaw search worked, in the usual way:\n\nBut human memory doesn’t work like that.\n\nPeople remember:\n\nThe raw tab data does not contain “melancholic”, “roadtrip”, “Eurovision”, or “midlife crisis but with acoustic guitar”.\n\nSo substring search was not enough.\n\nNaturally, I built an enrichment pipeline.\n\nEach artist got metadata:\n\nEach song got:\n\nThis meant that searching for:\n\n`trondheim`\n\ncould also match:\n\nAnd searching for:\n\n`melankolsk`\n\nmight surface the right heartbreak song, even if the original tab never contained that word.\n\nThis required… somewhat more LLM calls than is emotionally healthy.\n\nAt one point I had scripts serializing enrichment runs across thousands of entries, checkpointing JSON, resuming partial runs, salvaging truncated model output, and retrying fallback entries.\n\nThere is Python in this project that exists purely to detect whether an LLM died halfway through a JSON object and then gently staple the braces back on like a field medic.\n\nThis may have been a warning sign.\n\nMy enrichment scripts originally used CLI tools in the simplest possible way:\n\n```\nLLM CLI -p \"prompt\"\n```\n\nWhich works.\n\nIf by “works” you mean:\n\nThis is acceptable for casual use.\n\nIt is less charming when you are grinding through hundreds of enrichment calls because you want guitar-tab search to understand *vibes*.\n\nAt this point, even I had to admit that I was spending industrial amounts of machinery on a problem that would not survive first contact with a normal human conversation.\n\nGitHub Copilot CLI has an ACP server mode.\n\nACP (Agent Client Protocol) is a proper JSON-RPC interface. Sessions, prompts, streamed updates, config options — actual protocol plumbing, not terminal scraping.\n\nSo naturally my brain went:\n\n“Hm. If this is already a protocol, I can keep it alive.”\n\nThis is usually where projects start becoming strange.\n\nI wrote a Python wrapper that:\n\n`copilot --acp`\n\nSo now anything that speaks:\n\n```\nPOST /v1/chat/completions\n```\n\ncan talk to my local Copilot-backed proxy as if it were a normal OpenAI API.\n\nThis was supposed to be a weekend spike.\n\nIt worked quite a bit better than it had any right to.\n\nAt this point, I had:\n\nAll because I wanted better search for chord sheets.\n\nThis is the sort of engineering story you tell and then pause so people can quietly reconsider your judgment.\n\nIn my defense, I am from Northern Norway.\n\nWe do not always stop when a thing becomes unreasonable. Sometimes we just put on a thicker jacket and continue.\n\nA lot of “interactive” developer tools now sit on top of actual machine interfaces.\n\nIf you can find the protocol, you can often build smarter wrappers than the intended UX exposes.\n\nACP is a good example of that.\n\nProcess startup overhead is tolerable once.\n\nNot 10,000 times.\n\nKeeping the backend warm dropped latency from “why did I do this to myself” to “actually usable.”\n\nSubstring search is useful.\n\nSemantic LLM enrichment makes search feel like memory.\n\nThat was the entire point of this exercise, buried underneath a mountain of accidental systems engineering.\n\nThis proxy lives in a somewhat gray area.\n\nIt is a personal experiment.\n\nIt uses my own login.\n\nIt runs locally.\n\nIt is not a SaaS business, and Claude willing it never becomes one.\n\nSome projects are best appreciated as engineering curiosities rather than product ideas.\n\nPeople sometimes imagine software engineering as disciplined architecture guided by clear requirements.\n\nSometimes it is.\n\nSometimes it is:\n\n“I need guitar-tab search to understand emotional context.”\n\n…followed by:\n\nAnd then, several weekends later, you look at the repo and think:\n\n“Æ e faen ikke helt sikker på hvordan vi havna her.”\n\nBut the search works.\n\nAnd, in fairness, that bittersweet Trønderrock song *does* show up now.\n\nWhich is more than can be said for my sense of proportion.\n\n*Code: github.com/aweussom/agentry. Personal spike, not a maintained product.*", "url": "https://wpnews.pro/news/i-built-an-openai-compatible-proxy-for-github-copilot-because-search-was-too-to", "canonical_source": "https://dev.to/tommy_leonhardsen_81d1f4e/i-built-an-openai-compatible-proxy-for-github-copilot-because-search-was-too-stupid-to-understand-31de", "published_at": "2026-05-26 11:24:09+00:00", "updated_at": "2026-05-26 11:33:50.310472+00:00", "lang": "en", "topics": ["ai-tools", "ai-products", "ai-agents", "natural-language-processing", "generative-ai"], "entities": ["GitHub Copilot", "NorTabs-web", "agentry", "OpenAI"], "alternates": {"html": "https://wpnews.pro/news/i-built-an-openai-compatible-proxy-for-github-copilot-because-search-was-too-to", "markdown": "https://wpnews.pro/news/i-built-an-openai-compatible-proxy-for-github-copilot-because-search-was-too-to.md", "text": "https://wpnews.pro/news/i-built-an-openai-compatible-proxy-for-github-copilot-because-search-was-too-to.txt", "jsonld": "https://wpnews.pro/news/i-built-an-openai-compatible-proxy-for-github-copilot-because-search-was-too-to.jsonld"}}