Repository navigation
feat(assessment): Migrate user prompt to config #1153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
c6ec5c9
feat(assessment): move prompt into config `submission`, drop request …
vprashrex 2ccefd7
refactor(tests): clean up formatting in test_api_crud.py for readability
vprashrex d42a5e6
fix(validation): update variable names for clarity in validate_blob_c…
vprashrex b3bebbd
chore(assessment): remove PLAN.md from PR
vprashrex 0b92090
refactor(assessment): hoist input_schema to config_blob top-level
vprashrex c77b1f0
refactor(assessment): improve formatting of pre_filter topic_relevanc…
vprashrex c51111d
Merge branch 'main' into feat/assessment-submission-field
vprashrex bad15ca
Merge branch 'main' into feat/assessment-submission-field
vprashrex File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
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
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
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
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| import logging | ||
| import re | ||
| from typing import Literal | ||
|
|
||
| from pydantic import JsonValue, model_validator | ||
|
|
@@ -10,10 +12,15 @@ | |
| TextLLMParams, | ||
| ) | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
| # json_output_schema is validated shallowly at config time: it must be a non-empty | ||
| # object-typed dict. Provider strict-mode normalisation is a run-mode concern. | ||
| JSON_SCHEMA_OBJECT_TYPE = "object" | ||
|
|
||
| # {column} placeholders in a submission template; the capture group is the column name. | ||
| PLACEHOLDER_RE = re.compile(r"\{(\w+)\}") | ||
|
|
||
| # Default llm for a pre-filter call when the config does not override it. | ||
| DEFAULT_PREFILTER_PROVIDER = Provider.OPENAI | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nitpick: see if these constants can be moved into a separate |
||
| DEFAULT_PREFILTER_MODEL = "gpt-5.6-luna" | ||
|
|
@@ -44,6 +51,13 @@ class PreFilterParams(TextLLMParams): | |
| min_length=1, | ||
| description="The pre-filter's criteria (system instruction). Mandatory.", | ||
| ) | ||
| submission: str | None = Field( | ||
| default=None, | ||
| description=( | ||
| "Optional per-row prompt template with {column} placeholders for this " | ||
| "pre-filter. Placeholders must resolve against the blob-level input_schema." | ||
| ), | ||
| ) | ||
|
|
||
|
|
||
| class PreFilterBase(SQLModel): | ||
|
|
@@ -88,41 +102,21 @@ class TopicRelevanceFilter(PreFilterBase): | |
| ) | ||
|
|
||
|
|
||
| class DuplicateDetectionFilter(PreFilterBase): | ||
| """Pre-filter that flags items duplicating prior corpus content. | ||
|
|
||
| Its criteria live in ``params.instructions`` (like the assessment call). | ||
| """ | ||
|
|
||
| knowledge_base_id: str | None = Field( | ||
| default=None, | ||
| description="Vector store to compare against; defaults to the platform corpus when unset.", | ||
| ) | ||
| stop_on_fail: bool = Field( | ||
| default=False, | ||
| description=( | ||
| "If true, a failing verdict stops the chain and skips the assessment for " | ||
| "that item; if false, the verdict is just recorded and the assessment runs." | ||
| ), | ||
| ) | ||
|
|
||
|
|
||
| class AssessmentPreFilters(SQLModel): | ||
| """Optional pre-filters applied before the main assessment call.""" | ||
|
|
||
| topic_relevance: TopicRelevanceFilter | None = None | ||
| duplicate_detection: DuplicateDetectionFilter | None = None | ||
|
|
||
|
|
||
| class AssessmentTextParams(TextLLMParams): | ||
| """Text params + structured input/output schemas, scoped to assessment.""" | ||
| """Text params + structured output schema, scoped to assessment.""" | ||
|
|
||
| input_schema: dict[str, InputColumn] = Field( | ||
| submission: str = Field( | ||
| ..., | ||
| min_length=1, | ||
| description=( | ||
| "Per-column spec for BATCH submissions ({type, format}). Mandatory and " | ||
| "non-empty; every declared column must be present in every submission row." | ||
| "Per-row prompt template with {column} placeholders. Mandatory; every " | ||
| "placeholder must resolve against input_schema." | ||
| ), | ||
| ) | ||
| json_output_schema: dict[str, JsonValue] | None = Field( | ||
|
|
@@ -162,5 +156,49 @@ class AssessmentConfigBlob(SQLModel): | |
| comes from {{col}} prompt interpolation), and no post_processing. | ||
| """ | ||
|
|
||
| input_schema: dict[str, InputColumn] = Field( | ||
| ..., | ||
| min_length=1, | ||
| description=( | ||
| "Per-column spec for the BATCH `data` rows ({type, format}). Shared by the " | ||
| "pre-filter and assessment consumers, so it lives once at the blob root. " | ||
| "Mandatory and non-empty; every declared column must be present in every row." | ||
| ), | ||
| ) | ||
| pre_filters: AssessmentPreFilters | None = None | ||
| assessment: AssessmentCompletionConfig | ||
|
|
||
| @model_validator(mode="after") | ||
| def _validate_submission_placeholders(self): | ||
| """Every {column} in every submission template must be a declared input_schema key. | ||
|
|
||
| Pre-filter and assessment submissions both validate against the blob-level | ||
| input_schema. Each params dict is already plain (their own validators dumped the | ||
| typed params), so submissions are read via dict access. | ||
| """ | ||
| declared = set(self.input_schema) | ||
|
|
||
| blocks: list[tuple[str, str]] = [ | ||
| ("assessment", self.assessment.params.get("submission") or "") | ||
| ] | ||
| topic_relevance = self.pre_filters.topic_relevance if self.pre_filters else None | ||
| if topic_relevance is not None and topic_relevance.params.get("submission"): | ||
| blocks.append( | ||
| ( | ||
| "pre_filter topic_relevance", | ||
| str(topic_relevance.params["submission"]), | ||
| ) | ||
| ) | ||
|
|
||
| for block, template in blocks: | ||
| unknown = sorted(set(PLACEHOLDER_RE.findall(template)) - declared) | ||
| if unknown: | ||
| logger.error( | ||
| f"[_validate_submission_placeholders] Unknown placeholder(s) " | ||
| f"| block: {block} | unknown: {unknown} | declared: {sorted(declared)}" | ||
| ) | ||
| raise ValueError( | ||
| f"{block} submission references unknown input_schema column(s): " | ||
| f"{', '.join(unknown)}" | ||
| ) | ||
| return self | ||
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
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
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
Oops, something went wrong.
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Validate placeholders that contain non-word characters.
PLACEHOLDER_REonly matches\w+. A submission such asAssess {unknown-column}bypasses the unknown-column check and is accepted wheninput_schemacontains onlya. This violates the required validation of all{placeholder}references and can pass an unbound template to batch construction.Match the full placeholder grammar used at runtime. Add regression coverage for an undeclared placeholder with punctuation.
Also applies to: 193-195
🤖 Prompt for AI Agents