Fix filtering config save, auto-save, streamed results, improved AI prompt
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m7s
All checks were successful
Build and Push Docker Image / build (push) Successful in 9m7s
- Add missing fields to FilteringConfigSchema (aiParseFiles, startupAdvanceCount, conceptAdvanceCount, notifyOnEntry, notifyOnAdvance) — Zod was silently stripping them on save - Restore auto-save with 800ms debounce on config changes - Add staggered animations for filtering results (stream in one-by-one) - Improve AI screening prompt: file type label mappings, soft cap handling, missing documents = fail, better user prompt structure Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -149,7 +149,7 @@ const MAX_PARALLEL_BATCHES = 10
|
||||
const AI_SCREENING_SYSTEM_PROMPT = `You are an expert project screening assistant for an ocean conservation competition.
|
||||
|
||||
## Your Role
|
||||
Evaluate each project against the provided screening criteria. Be objective and base evaluation only on provided data.
|
||||
Evaluate each project against the provided screening criteria. Be objective and base evaluation only on provided data. Your goal is to identify projects that clearly FAIL the criteria — not to nitpick minor issues.
|
||||
|
||||
## Output Format
|
||||
Return a JSON object with this exact structure:
|
||||
@@ -179,12 +179,43 @@ Return a JSON object with this exact structure:
|
||||
- founded_year: when the company/initiative was founded (use for age checks)
|
||||
- ocean_issue: the ocean conservation area
|
||||
- file_count, file_types: uploaded documents summary
|
||||
- files[]: per-file details with file_type, page_count (if known), size_kb, detected_lang (ISO 639-3 language code like 'eng', 'fra'), lang_confidence (0-1), round_name (which round the file was submitted for), and is_current_round flag
|
||||
- files[]: per-file details (see File Type Reference below) with file_type, page_count (if known), size_kb, detected_lang (ISO 639-3 language code like 'eng', 'fra'), lang_confidence (0-1), round_name (which round the file was submitted for), and is_current_round flag
|
||||
- description: project summary text
|
||||
- tags: topic tags
|
||||
- If document content is provided (text_content field in files), use it for deeper analysis. Pay SPECIAL ATTENTION to files from the current round (is_current_round=true) as they are the most recent and relevant submissions.
|
||||
- If detected_lang is provided, use it to evaluate language requirements (e.g. 'eng' = English, 'fra' = French). lang_confidence indicates detection reliability.
|
||||
|
||||
## File Type Reference
|
||||
The file_type field uses these codes. When criteria mention document names, match them to the correct code:
|
||||
- EXEC_SUMMARY = Executive Summary
|
||||
- PRESENTATION = Pitch Deck / Presentation
|
||||
- BUSINESS_PLAN = Business Plan
|
||||
- VIDEO = Video
|
||||
- VIDEO_PITCH = Video Pitch
|
||||
- SUPPORTING_DOC = Supporting Document
|
||||
- OTHER = Other / miscellaneous document
|
||||
|
||||
IMPORTANT: Only evaluate page limits against the CORRECT document type. For example, a page limit on "executive summary" applies ONLY to files with file_type=EXEC_SUMMARY, not to pitch decks or other documents.
|
||||
|
||||
## How to Interpret Criteria
|
||||
- Treat criteria as reasonable guidelines written by a human, not as rigid legal rules.
|
||||
- When criteria say "soft cap", "approximately", "around", "about", or "reasonable amount", be LENIENT. A document that is 1-3 pages over a soft cap still meets criteria. Only flag if it is egregiously over (e.g. double the stated limit).
|
||||
- When criteria have NO softening language, treat them as firm but still use judgment — a 1-page overage on a hard limit is borderline, not an automatic fail.
|
||||
- Page count data may be unavailable (null) for some files. If page_count is null, do NOT penalize — only evaluate page limits when page_count is actually provided for that file.
|
||||
- Focus on the INTENT behind each criterion, not a hyper-literal reading.
|
||||
|
||||
## Missing Documents
|
||||
- If criteria mention document requirements (executive summary, pitch deck, etc.) and the project has ZERO files (file_count=0), this is a CLEAR FAIL. Every competition applicant is expected to upload documents.
|
||||
- "Where applicable" in criteria refers to edge cases within specific document types — it does NOT mean documents are optional.
|
||||
- A project with no uploaded documents at all should always have meets_criteria=FALSE unless the criteria explicitly say documents are optional.
|
||||
|
||||
## Decision Framework
|
||||
- Set meets_criteria=TRUE if the project satisfies the core intent of the criteria, even with minor imperfections (e.g. a few pages over a soft cap).
|
||||
- Set meets_criteria=FALSE when there is a clear, material violation: missing required documents entirely, startup far exceeding age limit, documents entirely in the wrong language, no visible ocean impact, etc.
|
||||
- When in doubt on a SOFT criterion (page lengths, formatting), set meets_criteria=TRUE with a lower confidence score and note the concern in reasoning.
|
||||
- When in doubt on a HARD criterion (age limits, language, having documents at all), set meets_criteria=FALSE.
|
||||
- Mention specific concerns in the reasoning field so the admin can review.
|
||||
|
||||
## Guidelines
|
||||
- Evaluate ONLY against the provided criteria, not your own standards
|
||||
- A confidence of 1.0 means absolute certainty; 0.5 means borderline
|
||||
@@ -192,7 +223,7 @@ Return a JSON object with this exact structure:
|
||||
- When criteria differ by category (e.g. stricter for STARTUP vs BUSINESS_CONCEPT), apply the appropriate threshold
|
||||
- When criteria mention regional considerations (e.g. African projects), use the country/region fields
|
||||
- Do not include any personal identifiers in reasoning
|
||||
- If project data is insufficient to evaluate, set confidence below 0.3`
|
||||
- If project data is insufficient to evaluate, set confidence below 0.3 and default meets_criteria to TRUE`
|
||||
|
||||
// ─── Field-Based Rule Evaluation ────────────────────────────────────────────
|
||||
|
||||
@@ -371,10 +402,16 @@ async function processAIBatch(
|
||||
// Sanitize user-supplied criteria
|
||||
const { sanitized: safeCriteria } = sanitizeUserInput(criteriaText)
|
||||
|
||||
// Build optimized prompt
|
||||
const userPrompt = `CRITERIA: ${safeCriteria}
|
||||
PROJECTS: ${JSON.stringify(anonymized)}
|
||||
Evaluate and return JSON.`
|
||||
// Build user prompt with clear structure
|
||||
const userPrompt = `## Screening Criteria
|
||||
The admin has defined the following requirements. Evaluate each project against ALL of these criteria:
|
||||
|
||||
${safeCriteria}
|
||||
|
||||
## Projects to Evaluate (${anonymized.length} total)
|
||||
${JSON.stringify(anonymized)}
|
||||
|
||||
Evaluate each project and return JSON with your assessment.`
|
||||
|
||||
const MAX_PARSE_RETRIES = 2
|
||||
let parseAttempts = 0
|
||||
|
||||
Reference in New Issue
Block a user