Add LLM client, prompt builders, and prompt templates - #16
Open
qu4rkn3t wants to merge 1 commit into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces the initial building blocks for Phase 2 “commit triage” LLM support: prompt templates for the flash/frontier stages, prompt assembly/splitting logic based on token budgets, and a Google (Gemini) LLM client abstraction intended to support token counting, structured output, and embeddings.
Changes:
- Added markdown prompt templates for the “flash” and “frontier” LLM stages.
- Implemented prompt construction utilities that assemble PR/commit/diff context and split prompts to fit within a token budget.
- Added a Google GenAI (Gemini) LLM client abstraction for counting tokens, generating text/structured outputs, and producing embeddings.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
| perf_keeper/commit_triage/templates/frontier.md | Adds the frontier-stage prompt template and JSON response shape guidance. |
| perf_keeper/commit_triage/templates/flash.md | Adds the flash-stage prompt template and JSON response shape guidance. |
| perf_keeper/commit_triage/prompts.py | Implements regression header + PR/commit blocks and token-budget prompt splitting. |
| perf_keeper/commit_triage/llm.py | Introduces the LLM client abstraction and a Google GenAI-backed implementation. |
Suppressed comments (5)
perf_keeper/commit_triage/prompts.py:19
perf_keeper.commit_triage.modelsdoes not exist in the repo; the models referenced here (CommitModel/FileModel/PRModel/RegressionContext) already exist inperf_keeper/models.py. As written, this import will raiseModuleNotFoundError.
from perf_keeper.commit_triage.models import (
CommitModel,
FileModel,
PRModel,
RegressionContext,
)
perf_keeper/commit_triage/llm.py:27
perf_keeper.commit_triage.modelsis not present in the repo, and the imported symbols here (CommitRanking,FlashDecision,FlashResponse,FrontierResponse) are not defined anywhere else. This will raiseModuleNotFoundError(and also makes the__all__entries invalid). Either add the missing models module or remove these imports/re-exports until the schemas exist.
from perf_keeper.commit_triage.models import (
CommitRanking,
FlashDecision,
FlashResponse,
FrontierResponse,
)
perf_keeper/commit_triage/llm.py:169
complete()callsgenerate_content()directly, so the retry/backoff logic in_request()is bypassed. This can make prompt generation flaky under rate limits or transient 5xx errors.
response = await self._client.aio.models.generate_content(
model=self.model.model_id,
contents=prompt,
config=types.GenerateContentConfig(
temperature=self._temperature,
perf_keeper/commit_triage/llm.py:183
complete_structured()bypasses_request()and callsgenerate_content()directly, so structured generations won't be retried on 429/5xx. Using_request()here helps avoid intermittent empty/partial results under load.
response = await self._client.aio.models.generate_content(
model=self.model.model_id,
contents=prompt,
config=types.GenerateContentConfig(
temperature=self._temperature,
perf_keeper/commit_triage/llm.py:200
embed()bypasses_request()and calls the embedding endpoint directly, so transient rate limits / server errors won't be retried.
logger.debug("Embedding with %s", EMBEDDING_MODEL)
response = await self._client.aio.models.embed_content(
model=EMBEDDING_MODEL,
contents=text,
)
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+9
to
+12
| from perf_keeper.commit_triage.config import ( | ||
| CONTEXT_BUDGET_FRACTION, | ||
| HUNK_HEADER_RE, | ||
| ) |
Comment on lines
+221
to
+223
| texts = [header, footer_template.replace("{commit_keys}", "")] + [ | ||
| block + ", ".join(keys) for block, keys in pr_blocks | ||
| ] |
Comment on lines
+14
to
+21
| from perf_keeper.commit_triage.config import ( | ||
| CONTEXT_BUDGET_FRACTION, | ||
| DEFAULT_MAX_OUTPUT_TOKENS, | ||
| DEFAULT_TEMPERATURE, | ||
| EMBEDDING_MODEL, | ||
| FALLBACK_CONTEXT_WINDOW, | ||
| MAX_RETRIES, | ||
| ) |
Comment on lines
+151
to
+154
| response = await self._client.aio.models.count_tokens( | ||
| model=self.model.model_id, | ||
| contents=text, | ||
| ) |
Comment on lines
+18
to
+23
| { | ||
| "commit_key": "<string>", | ||
| "triage_score": "<integer 0–100>", | ||
| "confidence": "<low | medium | high>", | ||
| "reasoning": "<string>" | ||
| } |
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.
Type of change
Description
Gemini LLM client built with google-genai SDK with support for structured output, token counting, and embeddings. Also includes the flash and frontier prompt builders, which handle context-window splitting when the commit set is too large for a single prompt. The design follows spec -> provider -> model.
Checklist before requesting a review
Testing
Passed tests in Phase 2 tests